Singleton pattern implementation
我在任何地方都看到了单例模式的这种特殊实现:
1 2 3 4 5 6 7 8 | + (CargoBay *)sharedManager { static CargoBay *_sharedManager = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _sharedManager = [[CargoBay alloc] init]; }); return _sharedManager; } |
这似乎被认为是一种良好的做法(尤其是来自卡戈贝)。
我唯一不明白的是第一行
为什么要将
这只是一个可读性、惯例和实践的问题。其实并不需要,因为:
一个。它的值永远不会被检查。在旧的单例实现中,曾经有著名的
1 2 3 4 5 6 7 8 | + (id)sharedInstance { static SomeClass *shared = nil; if (shared == nil) shared = [[SomeClass alloc] init]; return shared; } |
代码-要使此方法工作,必须将支持变量初始化为nil,因为如果第一次不是nil,它将错误地省略if部分中的alloc in it并返回一个垃圾指针。但是,对于gcd解决方案,不再需要nil检查——gcd处理"仅执行此代码一次"pragma。
二。但是:静态变量被隐式初始化为零。所以即使你只写了
三。为什么这可能是一个好的实践?因为,尽管我提到了前两个原因,但是让源代码的读者知道某个东西被显式初始化为零仍然更容易阅读。或者甚至可能存在一些不一致的实现,其中静态变量没有正确地自动初始化,然后应该采取这种措施。
您将其设置为零以确保获得干净的实例。
这是一个更易读的版本,您想做什么:
1 2 3 4 5 6 7 8 9 10 11 | + (GlobalVariables *)sharedInstance { // the instance of this class is stored here static GlobalVariables *myInstance = nil; // check to see if an instance already exists if (nil == myInstance) { myInstance = [[[self class] alloc] init]; } // return the instance of this class return myInstance; } |
但是周围有大量的文章显示了这可能是不安全的,因此,将您的方法和我发布的方法混合起来,您会得到:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // Declared outside Singleton Manager static SingletonClass *myInstance = nil; + (GlobalVariables *)sharedInstance { if (nil != myInstance) { return myInstance; } static dispatch_once_t pred; // Lock dispatch_once(&pred, ^{ // This code is called at most once per app myInstance = [[GlobalVariables alloc] init]; }); return myInstance; } |