For*_*est 1 singleton objective-c ios
最直接和最简单的实现是这样的
static MySingleton *_instance = nil;
+ (MySingleton *) instance
{
@synchronized (_instance)
{
if (_instance == nil)
{
_instance = [[MySingleton alloc] init];
}
return _instance;
}
}
Run Code Online (Sandbox Code Playgroud)
实际上我知道几个关于单身的热门帖子,比如 在iOS中实现Singleton 和pop 模板
所以我的问题是"上述实施的任何缺陷"?
是的,您的实施存在很大缺陷.该@synchronized指令变为调用objc_sync_enter和稍后调用objc_sync_exit.instance第一次调用方法时,_instance是nil.objc_sync_enter如果通过它nil,该函数不会锁定,正如您可以通过查看其源代码看到的那样.
因此,如果两个线程在初始化instance之前同时调用_instance,则将创建两个实例MySingleton.
此外,您应该将_instance变量放在函数中,除非您有理由将其公开给整个源文件.
iOS 4.0及更高版本的单例访问器的首选实现使用非常高效的dispatch_once函数,如下所示:
+ (MySingleton *)sharedInstance {
static MySingleton *theInstance;
static dispatch_once_t once;
dispatch_once(&once, ^{
theInstance = [[self alloc] init];
});
return theInstance;
}
Run Code Online (Sandbox Code Playgroud)
该dispatch_once功能在iOS 4.0之前不可用,因此如果您确实需要支持较旧的iOS版本(这不太可能),则必须使用效率较低的版本@synchronized.由于无法同步nil,因此可以在类对象上进行同步:
+ (MySingleton *)sharedInstance {
static volatile MySingleton *theInstance;
if (!theInstance) {
@synchronized (self) {
if (!theInstance)
theInstance = [[self alloc] init];
}
}
return theInstance;
}
Run Code Online (Sandbox Code Playgroud)