背景
很多时候,我们在网上,或者开源项目中,看到类似下面这样创建一个单例:
+(MyClass *)singleton { static MyClass *shared = nil; if(shared == nil) { shared = [[MyClass alloc] init]; } return shared;}
但是,上面的代码在很多层面是错误的。首先,它不是线程安全的,当多个线程调用这个创建方法时,我们无法确保正确创建了一个实例,有时在苹果的官方例子中也是这么写的。
如果你必须使用单例,可以使用dispatch_once()
。
dispatch_once()
安全地解决了上面存在的问题:
(1)它保证了在块中的代码将在应用中只调用一次
(2)它是线程安全的
(3)它比使用其他方法创建单例更快,比如使用@synchronize()
@implementation Singletonstatic Singleton *shareSingleton = nil;+(Singleton*) shareInstance { @synchronized(self){ //加锁 if (shareSingleton == nil) { shareSingleton = [[Singleton alloc] init]; } } return shareSingleton;}
最佳实践
所以,创建单例的最佳实践应该是:
+(MyClass *)singleton { static dispatch_once_t pred; static MyClass *shared = nil; dispatch_once(&pred, ^{ shared = [[MyClass alloc] init]; }); return shared;}
总结
在实际项目中,我们应该尽量避免过多使用单例,虽然单例不是什么魔鬼,但是能不用就不用。如果你必须使用单例,也要使用正确的方法来创建它。