While I was at Apple’s Cocoa Camp over summer, one of the speakers talked
rather passionately about the proper, thread-safe way to implement a singleton
in iOS, which I thought deserves more attention than it currently does on the
Web.

The Common Way

According to the first result on my Google search, a singleton should
be implemented as follows:

staticSingletonClass*sharedInstance=nil;// Get the shared instance and create it if necessary.+(SingletonClass*)sharedInstance{if(sharedInstance==nil){sharedInstance=[[superallocWithZone:NULL]init];}returnsharedInstance;}

Although this method is quick and easy, it is not thread-safe and the object constructor might be called multiple times if several threads access the method concurrently. We need a way to lock the constructor and insist that it be executed at most once. This is where Grand Central Dispatch comes in.

The ~Troublesome~ Thread-safe Way

GCD provides a neat API that makes concurrency programming in Cocoa convenient.
To implement a thread-safe singleton in Cocoa, all you need to do is the
following:

staticMyObject*singleton=nil;+(MyObject*)sharedInstance{NSLog(@"sharedInstance called.");if(nil!=singleton)returnsingleton;staticdispatch_once_tpred;// lockdispatch_once(&amp;pred,^{// this code is at most oncesingleton=[[MyObjectalloc]init];});returnsingleton;}

Let’s look at the code in detail. First, notice that the first few lines are
the same: we have a static variable for our singleton, and we check whether it
is nil whenever we access sharedInstance. If singleton is nil, allocate and
initialize it; otherwise, return it.

The real difference is where we use the dispatch_* types and functions. You may
think of dispatch_once_t as a type of lock that dispatch_once() uses to ensure
that the code is executed at most once. Here, we wrap up whatever code we wish
to be executed during the initialization of our singleton in a block. We then
pass the block as an argument to dispatch_once. (Here's a pretty good tutorial
on blocks.)

This implementation ensures that singleton is never executed more than once
even when multiple threads access sharedInstance concurrently: