单例是⼀个在 Cocoa 中很常⽤的模式了。对于⼀些希望能在全局⽅便访问的实例,或者在 app 的⽣命周期中只应该存在⼀个的对象,我们⼀般都会使⽤单例来存储和访问。在 Objective-C 中单例的公认的写法类似下⾯这样:
@implementation Singleton
+ (id)shared {
static Singleton *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
@end
在 Swift ⾥我们其实有⼀个更简单的保证线程安全的⽅式,那就是 let 代码如下:
class Singleton {
class var shared: Singleton {
struct Static {
static let instance: Singleton = Singleton()
}
return Static.instance
}
}
还有另⼀种更受⼤家欢迎,并被认为是 Swift 1.2 之前的最佳实践的做法。由于 Swift 1.2 之前class 不⽀持存储式的 property ,我们想要使⽤⼀个只存在⼀份的属性时,就只能将其定义在全局的 scope 中。值得庆幸的是,在 Swift 中是有访问级别的控制的,我们可以在变量定义前⾯加上 private 关键字,使这个变量只在当前⽂件中可以被访问。这样我们就可以写出⼀个没有嵌套的,语法上也更简单好看的单例了:
import Foundation
private let instance = Singleton()
class Singleton {
class var shared: Singleton {
return instance
}
}
在 Swift 1.2 以及之后,如果没有特别的需求,我们推荐使⽤下⾯这样的⽅式来写⼀个单例:
import Foundation
class Singleton {
private static let instance = Singleton()
class var shared: Singleton {
return instance
}
}