在单例的共享实例访问器中使用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直到圣诞节才创建我的对象,会发生什么?它不会立即返回,对吧?至少这似乎是中央快递的全部意义所在。
那么他们为什么要这么做呢?
发布于 2012-02-03 04:01:05
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()的好处是速度更快。它在语义上也更清晰,因为它还可以防止多个线程对共享实例执行分配初始化--如果它们都在同一时间尝试的话。它不允许创建两个实例。dispatch_once()的整个理念是“执行一次并且只执行一次”,这正是我们正在做的。
发布于 2012-02-03 04:00:10
因为它只会运行一次。因此,如果您尝试从不同的线程访问它两次,这不会造成问题。
Mike Ash在他的Care and Feeding of Singletons博客文章中有一个完整的描述。
并非所有的GCD块都是异步运行的。
https://stackoverflow.com/questions/9119042
复制相似问题