Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Apple recommend to use dispatch_once for implementing the singleton pattern under ARC?

People also ask

What does dispatch_ once do?

Executes a block object only once for the lifetime of an application.

How is Dispatch_once implemented?

The first ever call to dispatch_once with a given predicate, which executes the block. Calls to dispatch_once after the first call, but before the block finishes executing. Here, callers have to wait for the block before they proceed. Calls to dispatch_once after the first call and after the block has executed.


dispatch_once() is absolutely synchronous. Not all GCD methods do things asynchronously (case in point, dispatch_sync() is synchronous). The use of dispatch_once() replaces the following idiom:

+ (MyClass *)sharedInstance {
    static MyClass *sharedInstance = nil;
    @synchronized(self) {
        if (sharedInstance == nil) {
            sharedInstance = [[MyClass alloc] init];
        }
    }
    return sharedInstance;
}

The benefit of dispatch_once() over this is that it's faster. It's also semantically cleaner, because it also protects you from multiple threads doing alloc init of your sharedInstance--if they all try at the same exact time. It won't allow two instances to be created. The entire idea of dispatch_once() is "perform something once and only once", which is precisely what we're doing.


Because it will only run once. So if you try and access it twice from different threads it won't cause a problem.

Mike Ash has a full description in his Care and Feeding of Singletons blog post.

Not all GCD blocks are run asynchronously.