Creating singletons using dispatch_once

Love them or loathe them, sometimes you need to have a singleton. In fact every iOS and Mac OS application has at least one, UIApplication or NSApplication.

So what is a singleton? Wikipedia defines it as:

In software engineering, the singleton pattern is a design pattern used to implement the mathematical concept of a singleton, by restricting the instantiation of a class to one object.

Or as I would put it:

A singleton is a class, where only one instance of it can instantiated.

Although this is the actual definition of a singleton, this isn’t always the case in the world of Foundation. NSFileManger and NSNotificationCenter for example, are usually accessed through their class methods defaultManager and defaultCenter respectively. Although not strictly a singleton, these class methods return a shared instance of that class that developers can then access throughout their code. It is this approach that we will be looking at in this post.

There has always been a debate on the best way to implement the singleton pattern using Objective-C, and developers (including Apple) seem to have been changing their minds every couple of years. When Apple introduced Grand Central Dispatch (GCD) (in Mac OS 10.6 and iOS 4.0) they introduced a function that is perfect for implementing the singleton pattern.

This function is dispatch_once:

 void dispatch_once(
 dispatch_once_t *predicate,
 dispatch_block_t block);

This function takes a predicate (which is a long, that in reality acts as a BOOL) that the dispatch_once function uses to check if the block has already been dispatched. It also takes the block that you wish to only be dispatched once for the lifetime of the application, for us this is the instantiation of our shared instance.

Not only does dispatch_once mean that your code will only ever get run once, it is also thread safe, which means you don’t have to bother with using anything like @synchronized to stop things getting out of sync when using multiple threads and/or queues.

This is verified by Apple’s GCD Documentation:

If called simultaneously from multiple threads, this function waits synchronously until the block has completed.

So how would you use this in practise?

Well lets say you have a Account Manager class, and you want to access a shared instance of this class throughout your application. You can simply implement a class method like the one below:

+ (AccountManager *)sharedManager {
static AccountManager *sharedAccountManagerInstance = nil;
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
        sharedAccountManagerInstance = [[self alloc] init]; 
});
    return sharedAccountManagerInstance;
}

This means whenever you want access this shared instance all you need to do is:

AccountManager *accountManager = [AccountManager sharedManager];

And that’s all there is to it, you now have a shared instance that you can access throughout your application, which will only be created once.

This approach has many advantages:

  1. It is thread safe
  2. It will keep the static analyser happy
  3. It is compatible with Automatic Reference Counting (ARC)
  4. It only requires a small amount of code

The only disadvantage with this approach is that it will still allow a non shared instance to be created:

AccountManager *accountManager = [[AccountManager alloc] init];

Sometimes you will actually want this behaviour, but it is something you need to be aware of when you really only want one instance of a class to ever be instantiated.