Skip to content

Instantly share code, notes, and snippets.

@advantis
Created September 26, 2012 12:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save advantis/3787824 to your computer and use it in GitHub Desktop.
Save advantis/3787824 to your computer and use it in GitHub Desktop.
Retrospective of Singleton pattern in Cocoa
// Simple implementation (not thread-safe)
+ (Singleton *) sharedSingleton
{
static Singleton *instance;
if (nil == instance)
{
instance = [self new];
}
return instance;
}
// Using @synchronized directive (overhead on every call)
+ (Singleton *) sharedSingleton
{
static Singleton *instance;
@synchronized (self)
{
if (nil == instance)
{
instance = [self new];
}
}
return instance;
}
// Using Double-Checked Locking pattern (not really safe, depends on compiler)
// See http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf
+ (Singleton *) sharedSingleton
{
static Singleton * volatile instance;
if (nil == instance)
{
@synchronized (self)
{
if (nil == instance)
{
instance = [self new];
}
}
}
return instance;
}
// Using OS-specific atomic operations (possible temporary creation of two instances)
+ (Singleton *) sharedSingleton
{
static Singleton * volatile instance;
while (nil == instance)
{
Singleton *temp = [self new];
if (!OSAtomicCompareAndSwapPtrBarrier(0x0, temp, &instance))
{
[temp release];
}
}
return instance;
}
// Using the “Method Swizzling” technique (impact on superclases implementation)
static Singleton *instance;
+ (Singleton *) sharedSingleton
{
@synchronized(self)
{
if (nil == instance)
{
instance = [self new];
Method origMethod = class_getClassMethod(self, _cmd);
Method newMethod = class_getClassMethod(self, @selector(someMethod));
method_exchangeImplementations(origMethod, newMethod);
}
}
return instance;
}
+ (Singleton *) someMethod
{
return instance;
}
// Using Grand Central Dispatch (only for iOS >= 4.0)
+ (Singleton *) sharedSingleton
{
static Singleton *instance;
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{ instance = [self new]; });
return instance;
}
// Using Cocoa architecture (premature instantiation, impact on superclases implementation)
static Singleton *instance;
+ (void) initialize
{
if ([Singleton class] == self)
{
instance = [self new];
}
}
+ (Singleton *) sharedSingleton
{
return instance;
}
// Using pthread
static Singleton *instance;
static void SingletonInit() { instance = [Singleton new]; }
+ (Singleton*) sharedSingleton
{
static pthread_once_t once_control = PTHREAD_ONCE_INIT;
pthread_once(&once_control, SingletonInit);
return instance;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment