ios - 为什么苹果推荐使用 dispatch_once 来实现 ARC 下的单例模式?

在 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/

相关文章:

ios - 在 Swift 中实例化并展示一个 viewController

objective-c - 如何将堆栈跟踪打印到控制台/登录 Cocoa?

objective-c - NSDate 获取年/月/日

iphone - 如何检测 iPhone 5(宽屏设备)?

objective-c - Objective-C中强弱的区别

ios - UIImageView 在设备上的启动屏幕中缺少图像

iphone - 我们如何以编程方式检测设备在哪个 iOS 版本上运行?

objective-c - 将项目转换为使用 ARC 时, "switch case is in p

ios - 如何使用 NSURLConnection 与 SSL 连接以获得不受信任的证书?

ios - 如何在 NSLog 中打印 bool 标志?