Singleton Pattern in Objective C

Objective C unfortunately does not support the singleton pattern with which Java developers are familiar.  The reason stems from the fact that there are no private methods in Objective C to prevent the init constructor method from being invoked.

There is however a simple hack that can provide the benefits of the singleton pattern in Objective C.  Singleton classes tend to be managers of data so let’s go with the class name JFDataManager in this example.

 

Going Global

Since Objective C doesn’t support the singleton pattern we have to resort to using a global variable the way C does.

A global variable can be referenced from anywhere in the application and since we want to discourage the direct manipulation of this global variable we need to hide it.  The best place to hide it is the one place nobody will look, in definition file for that class, JFDataManager.m.

Doing so will render it unlikely of being referenced since we’re never supposed to #import or #include *.m files.  Note that I said unlikely.  Technically any inquisitive developer can find and reference it.

The declaration might look something like this…

JFDataManager *__JFDataManager_sharedInstance__ = nil;

Since the class name was previously declared in JFDataManager.h this instance is completely legal.  Now since we’re dealing with global variables there is the risk of name collision so it’s good practice to go with an instance name that includes the class name as I’ve done above.

 

Exposing It The Recommended Way

The convention for telling developers that they should access the singleton instance and not instantiate their own is to offer a class method beginning with the word “shared”.  You may have noticed a sharedApplication method exposed by the NSApplication and UIApplication classes.  You’ll want to follow this approach.

JFDataManager will expose the below method…

+ (JFDataManager *) sharedManager;

The implementation of this method will return the shared instance and if necessary lazy-initialize it like this…

+ (JFDataManager *) sharedManager {
	if (__JFDataManager_sharedInstance__ == nil) {
		__JFDataManager_sharedInstance__ = [[JFDataManager alloc] init];
	}
	return __JFDataManager_sharedInstance__;
}

 

Getting the shared instance is as simple as invoking the sharedManager method.  That’s really all there is to using the singleton pattern in Objective C.  It involves a bit of trickery but Objective C developers using your class will enjoy the same benefits Java developers already do.