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.)