Design Patterns book, open to section about singletons
Make sure you're using it right.

There are many ways to create a singleton in Objective-C. Most of them are wrong. Read on for a rundown of your options.

Sidenote: I feel compelled to ask you before we begin, are you sure you want a singleton? The sentiment among many developers these days is that singletons are vastly overused, and have become a bit of an anti-pattern. Read this for a more in-depth discussion.

1. Probably the original way

+ (instancetype)sharedInstance {
    static id sharedInstance = nil;

    if (!sharedInstance) {
        sharedInstance = [[self alloc] init];
    }

    return sharedInstance;
}

This is (or at least was) probably the most commonly used method for creating a singleton. It is also terrible. Don’t ever use it.

What’s the problem? It’s not thread-safe, so you could easily end up with different threads having different copies of the sharedInstance. Oh, I can hear you saying now, “I’m never going to use that singleton in a different thread”. Really, are you sure? You are never going to dispatch off some operation, that somewhere down the chain accesses that singleton? And no one else is ever going to come into the code and do it either, right? Because once that happens, you have a very nasty heisenbug on your hands.

2. Safer, but still not great

+ (instancetype)sharedInstance {
    static id sharedInstance = nil;

    @synchronized(self) {
        if (!sharedInstance) {
            sharedInstance = [[self alloc] init];
        }
    }

    return sharedInstance;
}

This is the naive way to fix the first method. And it does make the singleton method thread-safe. But there’s a big performance penalty – @synchronized is slow. And if sharedInstance is being called a lot, it can really add up.

3. Let’s get primitive

To try to fix the performance of method #2, you could try to replace the @synchronized directive with a lower level synchronization construct (like locks, or atomic operations). I’m not going to put an example here, because I’d probably get it wrong. And so would you for that matter, so don’t bother. There’s a better performance option anyway.

4. And now for something completely different

static id sharedInstance = nil;

+ (void)initialize {
    sharedInstance = [[self alloc] init];
}

+ (instancetype)sharedInstance
    return sharedInstance;
}

This one is not a commonly seen method, and it takes a completely different approach from all the other techniques. It relies on the fact that the initialize method is called on every class exactly once before the class is used. It’s thread-safe, and has no performance overhead. Because of that, it used to be my preferred technique (back in the bad old days). However, it does have a few small drawbacks:

– It forces the singleton to be initialized as soon as the class is accessed. Now since it’s a singleton class, you were probably about to access the singleton method anyway. But it’s not quite as lazy as the other methods.

– There is some potential weirdness if your singleton class is sub-classed. Why would you sub-class a singleton? I don’t know, but I’ve seen it happen.

– It’s just not as clean as the other methods. Rather than being self-contained in sharedInstance, the logic is in three different places.

5. The Right Way

+ (instancetype)sharedInstance
{
    static dispatch_once_t once;
    static id sharedInstance;

    dispatch_once(&once, ^{
        sharedInstance = [[self alloc] init];
    });

    return sharedInstance;
}

Since the introduction of GCD, this has become the canonical way of writing a singleton. dispatch_once ensures that the singleton gets created only once, in a thread-safe manner. And it has better performance than any other synchronization method.

So just write your singleton The Right Way, and save yourself some grief.