esilver
esilver

Reputation: 28473

How is this static singleton member getting set in Obj-C?

I just did an Analyze of code that I use from a public library, and XCode pointed out a problem with the line that begins with [[[self alloc]:

static MyClass *_sharedInstance = nil;

+ (MyClass*)sharedInstance
{
    if (_sharedInstance != nil) {
        return _sharedInstance;
    }

    @synchronized(self) {
        if (_sharedInstance == nil) {
            [[[self alloc] init] autorelease];
        }
    }

    return _sharedInstance;
}

As I look at this line, I have no idea how it is possible for _sharedInstance to ever get assigned. Can anyone explain to me why this code works? I would have expected that you need to write:

_sharedInstance = [[[self alloc] init] autorelease];

Upvotes: 0

Views: 105

Answers (2)

bbum
bbum

Reputation: 162722

This is yet another example of way overthinking a +sharedInstance method to the point where it is confusing, at best, and only works because of other shenanigans (like overriding release).

Just do this and be done with it:

+ (id)sharedInstance
{
    static MyClass *sharedInstance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
}

Simple, straightforward, and does not preclude using MyClass as a non-singleton. The one flaw in this is if +sharedInstance is called recursively, it'll deadlock, but +sharedInstance recursively is generally a bad sign anyway.

Upvotes: 3

Nikolai Ruhe
Nikolai Ruhe

Reputation: 81868

It might be set in alloc, rather than init. This would prevent creation of another instance in a recursive call from within init.

Explanation:

It's common for complex singletons to do a lot of setup. This setup could be complex, touching more than only this class. It happens that the singleton is requested from (deep) within this setup. If the _sharedInstance variable would not be set before calling init, two instances would be created.

Upvotes: 0

Related Questions