在 ARC 下单例的共享实例访问器中使用 dispatch_once 的确切原因是什么?
+ (MyClass *)sharedInstance
{
// Static local predicate must be initialized to 0
static MyClass *sharedInstance = nil;
static dispatch_once_t onceToken = 0;
dispatch_once(&onceToken, ^{
sharedInstance = [[MyClass alloc] init];
// Do any other initialisation stuff here
});
return sharedInstance;
}
在后台异步实例化单例不是一个坏主意吗?我的意思是如果我请求该共享实例并立即依赖它会发生什么,但是 dispatch_once 需要到圣诞节才能创建我的对象?它不会立即返回对吗?至少这似乎是 Grand Central Dispatch 的重点。
那么他们为什么要这样做呢?
最佳答案
dispatch_once()
是绝对同步的。并非所有 GCD 方法都是异步执行的(例如,dispatch_sync()
是同步的)。 dispatch_once()
的使用替换了以下成语:
+ (MyClass *)sharedInstance {
static MyClass *sharedInstance = nil;
@synchronized(self) {
if (sharedInstance == nil) {
sharedInstance = [[MyClass alloc] init];
}
}
return sharedInstance;
}
dispatch_once()
的好处是它更快。它在语义上也更干净,因为它还可以保护您免受多个线程执行 sharedInstance 的 alloc init 的影响——如果它们都在同一确切时间尝试。它不允许创建两个实例。 dispatch_once()
的整个想法是“执行一次且仅一次”,这正是我们正在做的。
https://stackoverflow.com/questions/9119042/