Thursday, January 26, 2012

Singleton in Objective C

Method 1:
@interface SomeManager : NSObject
+ (id)sharedManager;
@end

@implementation SomeManager

+ (id)sharedManager {
    static id sharedManager = nil;

    if (sharedManager == nil) {
        sharedManager = [[self alloc] init];
    }

    return sharedManager;
}

@end
The astute reader will notice, of course, that this isn’t thread-safe. I got rid of the @synchronized (self)because it won’t do the right thing; depending on what actual class is sent +sharedManager, the value of self will be different!
Method 2:
One way to do this would be to create your singleton instance in +initialize since it will always be run, on a single thread, before any other methods in your class:

@implementation SomeManager

static id sharedManager = nil;

+ (void)initialize {
    if (self == [SomeManager class]) {
        sharedManager = [[self alloc] init];
    }
}

+ (id)sharedManager {
    return sharedManager;
}

@end
By doing this, you avoid the performance bottleneck of @synchronized taking a recursive lock every time+sharedManager is invoked.


Method 3 (ARC version):

+ (id)sharedInstance
{
  static dispatch_once_t pred = 0;
  __strong static id _sharedObject = nil;
  dispatch_once(&pred, ^{
    _sharedObject = [[self alloc] init]; // or some other init method
  });
  return _sharedObject;
}

No comments:

Post a Comment