3 回答
TA贡献1900条经验 获得超5个赞
TL;DR:使用类常数如果您正在使用SWIFT1.2或更高版本,并且嵌套结构如果需要支持早期版本,请使用此方法。
根据我使用SWIFT的经验,有三种方法可以实现Singleton模式,它们支持延迟初始化和线程安全。
类常数
class Singleton { static let sharedInstance = Singleton()}
此方法支持延迟初始化,因为Swift延迟初始化类常量(和变量),并且通过let
..
SWIFT 1.2中引入了类常数。如果需要支持SWIFT的早期版本,请使用下面的嵌套结构方法或全局常量。
嵌套结构
class Singleton { class var sharedInstance: Singleton { struct Static { static let instance: Singleton = Singleton() } return Static.instance }}
这里我们使用嵌套结构的静态常数作为类常量。这是SWIFT1.1及更早版本中缺少静态类常量的一种解决方法,并且仍然可以解决函数中缺少静态常量和变量的问题。
派遣一次
传统的目标-C方法移植到SWIFT。我相当肯定,与嵌套的struct方法相比没有什么优势,但我还是把它放在这里,因为我发现语法上的差异很有趣。
class Singleton { class var sharedInstance: Singleton { struct Static { static var onceToken: dispatch_once_t = 0 static var instance: Singleton? = nil } dispatch_once(&Static.onceToken) { Static.instance = Singleton() } return Static.instance! }}
TA贡献1155条经验 获得超0个赞
由于Apple现在已经澄清静态struct变量被初始化为延迟并被包装在调度_ONE中(请参阅文章末尾的注释),我认为我的最后解决方案将是:
class WithSingleton { class var sharedInstance :WithSingleton { struct Singleton { static let instance = WithSingleton() } return Singleton.instance }}
这利用了静态结构元素的自动延迟、线程安全初始化,向使用者安全地隐藏了实际实现,使所有内容保持紧凑的可读性,并消除了一个可见的全局变量。
苹果已经澄清,延迟初始化程序是线程安全的,因此不需要dispatch_once
或类似的保护
全局变量的延迟初始化器(也适用于结构和枚举的静态成员)将在第一次访问全局变量时运行,并以调度_ONE的形式启动,以确保初始化是原子的。这使得在代码中使用调度一次的方法很酷:只需使用初始化器声明一个全局变量,并将其标记为私有变量即可。
- 3 回答
- 0 关注
- 678 浏览
添加回答
举报