iOS8 + Swift:创建一个真正的单例类[重复]

Posted

技术标签:

【中文标题】iOS8 + Swift:创建一个真正的单例类[重复]【英文标题】:iOS8 + Swift: Create a true singleton class [duplicate] 【发布时间】:2015-01-09 14:35:59 【问题描述】:

我正在 Swift 中创建一个单例类,如下所示:

class SingletonClass 

    class var sharedInstance: SingletonClass 
        struct Singleton 
            static let instance = SingletonClass()
        

        return Singleton.instance
    


    var a: Int?
    var b: Int?
    var c: Int?

这允许我从任何地方访问共享实例:

SingletonClass.sharedInstance

虽然这可行,但它并没有使这个实例成为整个系统中唯一可能的实例,而这正是单例的全部意义所在。 这意味着我仍然可以创建一个全新的实例,例如:

let DifferentInstance: SingletonClass = SingletonClass()

共享实例不再是唯一的。 所以我的问题是:在 Swift 中有没有一种方法可以创建一个真正的单例类,在这个类中,系统范围内只有一个实例是可能的?

【问题讨论】:

为什么要强制规定没有人可以创建类的实例? @DanielGalasko,举例来说,如果你有一个物理资源,你的班级正在管理与之交互。与同一资源交互的多个实例可能会导致严重或致命的问题。或者它只是与一个不能一次打开多次的数据库进行交互。 我听到了,但不幸的是,没有办法保护您的框架免受其他人的无知或愚蠢的影响。您最好的选择是在单例实例化中定义大多数对象设置方法,例如数据库 url 等... 【参考方案1】:

只需将您的初始化程序声明为私有:

private init() 

现在只能从同一个文件中创建新实例。

【讨论】:

【参考方案2】:

全局变量、嵌套结构、dispatch_once。选择一个。

全局变量的惰性初始化器(也适用于 structs 和 enums)在第一次访问 global 时运行,并且 作为 dispatch_once 启动以确保初始化是 原子。这为在代码中使用 dispatch_once 提供了一种很酷的方式: 只需使用初始化程序声明一个全局变量并标记它 私人的。

private let _singletonInstance = SingletonClass()
class SingletonClass 
  class var sharedInstance: SingletonClass 
    return _singletonInstance
  

更多信息在这里。 https://github.com/hpique/SwiftSingleton

【讨论】:

【参考方案3】:

你误解了单例的本质。单例的目的是提供单例,而不是防止邪恶。我可以制作另一个 UIApplication 而不是 sharedApplication,但这将是愚蠢的,因为它不会是 sharedApplication。我可以创建另一个 NSNotificationCenter 而不是 defaultCenter,但这将是愚蠢的,因为它不会是 defaultCenter。关键不是要阻止我做傻事,而是要提供一个工厂单例,这就是你已经在做的事情。别担心,开心就好。

【讨论】:

我正要评论同样的事情。几乎不可能防止“愚蠢”(因为没有更好的词)。如果人们想分配新的实例然后让他们,只需记录它不是这样做的方法,并且所述行为是未定义的 是的,好吧,我在“愚蠢”和“邪恶”之间有点纠结,这就是我同时使用两者的原因。 :) OOP 编程是一个契约。任何人都可以违约(例如,如果你真的想的话,你总是可以逃避隐私限制)。然而,这个想法不是。 然而,可用性的主要概念之一是可供性的概念。减少可能使某些东西更易于使用。尤其是当解决方案与将初始化程序设为私有一样简单时(请参阅我的答案),我认为这样做更好。此外,***上关于单例的第一行是“在软件工程中,单例模式是一种将类的实例化限制为一个对象的设计模式。”共享实例和单例之间是有区别的。 另外,拥有多个通知中心的想法并不疯狂,但拥有多个Camera对象的想法,例如,当计算机上只有一个时,不仅不合逻辑,而且会导致低水平的严重问题。有时,为了防止严重的崩溃或错误,实际上需要真正的单例(强制执行单个实例)。 @matt 我实际上必须同意 drawag 在这里。您给出了具有共享实例的类的完美示例,如果不使用这些实例将非常愚蠢:)。但这些只是非常有用的共享实例,而不是单例。根据定义,单例类在任何给定时间只能有一个现有实例。顺便说一句,在我目前的具体情况下,我使用真正的单例实际上并不重要,但我很感兴趣的是提出如何这样做的问题。不知何故,我设法错过了明显的私有初始化解决方案。我想这是工作量:)

以上是关于iOS8 + Swift:创建一个真正的单例类[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何创建一个完美的单例模式

如何创建一个完美的单例模式,你会么?

Spring的单例模式底层实现学习笔记

Ruby 中 BasicObject 的单例类的单例类

JAVA设计模式中的单例模式

如何在整个应用程序中创建和注入用户特定的单例类?