objective-c singleton macro that supports both ARC enabled and disabled projects
Im a big fan of Matt Gallagher’s singleton macro and have been useing a slightly modified version of it by Oliver Jones.
Lately however I’ve been enabling ARC in my projects and came across the problem of including the macro only to have xcode winge to me about all the release methods. Im using a library so I wanted my macro to support both enviroments. I initially went back to Matt’s macro to see if he perhaps updated for this situation but it seems not so. I was also suprised to see that i couldnt really find any thing else usefull on the subject.
So back to basics, my buddy Adam Phin and I figured we can detect if ARC is enabled with the following preproccessing flag
#if __has_feature(objc_arc)
Using this flag we came up with this macro. You can download it here.
//
// SynthesizeSingleton.h
// Copyright 2009 Matt Gallagher. All rights reserved.
//
// Modified by Oliver Jones.
//
// Permission is given to use this source code file without charge in any
// project, commercial or otherwise, entirely at your risk, with the condition
// that any redistribution (in part or whole) of source code must retain
// this copyright and permission notice. Attribution in compiled projects is
// appreciated but not required.
//
#if __has_feature(objc_arc)
#define SYNTHESIZE_SINGLETON_FOR_CLASS(classname, accessorname) \
+ (classname *)accessorname\
{\
static classname *accessorname = nil;\
static dispatch_once_t onceToken;\
dispatch_once(&onceToken, ^{\
accessorname = [[classname alloc] init];\
});\
return accessorname;\
}
#else
#define SYNTHESIZE_SINGLETON_FOR_CLASS(classname, accessorname) \
static classname *shared##classname = nil; \
+ (void)cleanupFromTerminate \
{ \
classname *temp = shared##classname; \
shared##classname = nil; \
[temp dealloc]; \
} \
+ (void)registerForCleanup \
{ \
[[NSNotificationCenter defaultCenter] addObserver:self \
selector:@selector(cleanupFromTerminate) \
name:UIApplicationWillTerminateNotification \
object:nil]; \
} \
+ (classname *)accessorname \
{ \
static dispatch_once_t p; \
dispatch_once(&p, \
^{ \
if (shared##classname == nil) \
{ \
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; \
shared##classname = [[self alloc] init]; \
[self registerForCleanup]; \
[pool drain]; \
} \
}); \
return shared##classname; \
} \
+ (id)allocWithZone:(NSZone *)zone \
{ \
static dispatch_once_t p; \
__block classname* temp = nil; \
dispatch_once(&p, \
^{ \
if (shared##classname == nil) \
{ \
temp = shared##classname = [super allocWithZone:zone]; \
} \
}); \
return temp; \
} \
- (id)copyWithZone:(NSZone *)zone { return self; } \
- (id)retain { return self; } \
- (NSUInteger)retainCount { return NSUIntegerMax; } \
- (oneway void)release { } \
- (id)autorelease { return self; }
#endif

Hello. I'm Byron Salau a Melbourne based developer who's an absolute objective-c and javascript junkie!