单例规则
- 单例必须是唯一的(要不怎么叫单例?) 在程序生命周期中只能存在一个这样的实例。单例的存在使我们可以全局访问状态。例如:
NSNotificationCenter, UIApplication和NSUserDefaults。
为保证单例的唯一性,单例类的初始化方法必须是私有的。这样就可以避免其他对象通过单例类创建额外的实例。
考虑到规则1,为保证在整个程序的生命周期中值有一个实例被创建,单例必须是线程安全的。并发有时候确实挺复杂,简单说来,如果单例的代码不正确,如果有两个线程同时实例化一个单例对象,就可能会创建出两个单例对象。也就是说,必须保证单例的线程安全性,才可以保证其唯一性。通过调用dispatch_once,即可保证实例化代码只运行一次。
Objective - C
@interface Kraken : NSObject
@end
@implementation Kraken
+ (instancetype)sharedInstance {
static Kraken *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[Kraken alloc] init];
});
return sharedInstance;
}
@end
Swift
1. 最丑陋方法(Swift皮,Objective-C心)
class TheOneAndOnlyKraken {
class var sharedInstance: TheOneAndOnlyKraken {
struct Static {
static var onceToken: dispatch_once_t = 0
static var instance: TheOneAndOnlyKraken? = nil
}
dispatch_once(&Static.onceToken) {
Static.instance = TheOneAndOnlyKraken()
}
return Static.instance!
}
}
2. 结构体方法(“新瓶装老酒)
class TheOneAndOnlyKraken {
class var sharedInstance: TheOneAndOnlyKraken {
struct Static {
static let instance = TheOneAndOnlyKraken()
}
return Static.instance
}
}
3.全局变量方法(“单行单例”方法)
private let sharedKraken = TheOneAndOnlyKraken()
class TheOneAndOnlyKraken {
class var sharedInstance: TheOneAndOnlyKraken {
return sharedKraken
}
}
4. 最完美的
class TheOneAndOnlyKraken {
static let sharedInstance = TheOneAndOnlyKraken()
private init() {} //This prevents others from using the default '()' initializer for this class.
}