Edit: This implementation obsoleted with ARC. Please have a look at How do I implement an Objective-C singleton that is compatible with ARC? for correct implementation.
All the implementations of initialize I've read in other answers share a common error.
+ (void) initialize { _instance = [[MySingletonClass alloc] init] // <----- Wrong! } + (void) initialize { if (self == [MySingletonClass class]){ // <----- Correct! _instance = [[MySingletonClass alloc] init] } }
The Apple documentation recommend you check the class type in your initialize block. Because subclasses call the initialize by default. There exists a non-obvious case where subclasses may be created indirectly through KVO. For if you add the following line in another class:
[[MySingletonClass getInstance] addObserver:self forKeyPath:@"foo" options:0 context:nil]
Objective-C will implicitly create a subclass of MySingletonClass resulting in a second triggering of +initialize.
You may think that you should implicitly check for duplicate initialization in your init block as such:
- (id) init { <----- Wrong! if (_instance != nil) { // Some hack } else { // Do stuff } return self; }
But you will shoot yourself in the foot; or worse give another developer the opportunity to shoot themselves in the foot.
- (id) init { <----- Correct! NSAssert(_instance == nil, @"Duplication initialization of singleton"); self = [super init]; if (self){ // Do stuff } return self; }
TL;DR, here's my implementation
@implementation MySingletonClass static MySingletonClass * _instance; + (void) initialize { if (self == [MySingletonClass class]){ _instance = [[MySingletonClass alloc] init]; } } - (id) init { ZAssert (_instance == nil, @"Duplication initialization of singleton"); self = [super init]; if (self) { // Initialization } return self; } + (id) getInstance { return _instance; } @end
(Replace ZAssert with our own assertion macro; or just NSAssert.)