I’ll leave any debate over whether the Singleton design pattern and global variables are a good thing or not. But, as I see it, as soon as a constants.h file is added to a project, a singleton has effectively been made and it can be a slippery slope to the full class implementation. I use it rarely, but find a lot of value in this pattern when I do need it; I use it for holding constants that are based on class methods and complex data types (like dictionaries), which the standard non-class based constants.h/.m implementation doesn’t allow. Simple constants, ones based on core data types like NSString, however, really should just stick with the non-class implementation as this is overkill.

ObjCsingleton.h



@interface <#CLASSNAME#> : NSObject {

}

#pragma mark -
#pragma mark Class and Singleton Methods
#pragma mark -

+ (<#CLASSNAME#> *) sharedLib;

@end


ObjCsingleton.m



#import "<#CLASSNAME#>.h"


@implementation <#CLASSNAME#>

static <#CLASSNAME#> *sharedInstance = nil;

#pragma mark -
#pragma mark Class and Singleton methods
#pragma mark -

+ (<#CLASSNAME#> *)sharedLib {
@synchronized(self) {
if (sharedInstance == nil) {
sharedInstance = [[<#CLASSNAME#> alloc] init];
}
}
return sharedInstance;
}

+ (id)allocWithZone:(NSZone *)zone {
@synchronized(self) {
if (sharedInstance == nil) {
sharedInstance = [super allocWithZone:zone];
return sharedInstance; // assignment and return on first allocation
}
}
return nil; // on subsequent allocation attempts return nil
}

- (id)copyWithZone:(NSZone *)zone {
return self;
}

- (id)retain {
return self;
}

- (unsigned)retainCount {
return UINT_MAX; // denotes an object that cannot be released
}

- (void)release {
//do nothing
}

- (id)autorelease {
return self;
}

#pragma mark -
#pragma mark Init
#pragma mark -

//----------------------------------------------------------
// - (id) init
//
//----------------------------------------------------------
- (id) init {
self = [super init];
if (self) {

// do something

}
return self;
}

@end


How to use



Instantiating



I typically have initialization occur in windowDidLoad: (Cocoa) or applicationDidFinishLoading (iOS) to ensure it is instantiated early and useful at all points of the application. The sharedLib method handles initialization.


OCMySingletonObj *mySingleton = [OCMySingletonObj sharedLib];


Properties



Properties don't work the same way here because dot notation cannot be used. In order to get the value of a property, you have to call the method equivalent. So, say the above class OCConstantsLib has a public property propertyName, complete with property and synthesize declarations...

//ocConstants = [OCConstantsLib sharedLib];
NSDataType *dataName = [[OCConstantsLib sharedLib] propertyName];


That's it. No muss, no fuss.