Crafting Singletons
The UIApplication and UIDevice classes let you access information about the currently running application and the device hardware it is running on. They do so by offering singletons—that is, a sole instance of a class in the current process. For example, [UIApplication sharedApplication] returns a singleton that can report information about the delegate it uses, whether the application supports shake-to-edit features, what windows are defined by the program, and so forth.
Most singleton objects act as control centers. They coordinate services, provide key information, and direct external access, among other functionality. If you have a need for centralized functionality, such as a manager that accesses a web service, a singleton approach ensures that all parts of your application coordinate with the same central manager.
Building a singleton takes very little code. You define a static shared instance inside the class implementation and add a class method pointing to that instance. In this snippet, which is taken from the tagging example of Chapter 6, “Assembling Views and Animations,” the instance is built the first time it is requested:
@implementation ViewIndexer static ViewIndexer *sharedInstance = nil; +(ViewIndexer *) sharedInstance { if(!sharedInstance) sharedInstance = [[self alloc] init]; return sharedInstance; } // Class behavior defined here @end
To use this singleton, call [ViewIndexer sharedInstance]. This returns the shared object and lets you access any behavior that the singleton provides. For thread-safe use, you may want to use a more guarded approach to singleton creation, such as this one:
+ (ViewIndexer *)sharedInstance { static dispatch_once_t pred; dispatch_once(&pred, ^{ sharedInstance = [[self alloc] init]; }); return sharedInstance; }