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

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.

Leave a Comment