There are many pages of discussions around the internet about whether or not you should use global variables in your applications. I’m not going to to into the depths of these discussions, but I have come to live by the following ethos when it comes to using global variables in my application;

Use them sparingly; Having too many global variables floating around makes it very hard to keep track of what’s going on. I never use more than one global object for each logical section of my code - even if that object contains a handful of other objects from that section.

But you do sometimes need them; I once wrote a small game where I decided not to use my own globals at all. Truth be told, I ended up with a bit of a mess - a large number of similar constructors with a numbers of parameters to link my objects together. Sure, the units were technically separate and didn’t rely on each other - but the reality was, that when you get deep enough into your code - some classes are only ever going to be used in this project (view controllers etc).

Use them when it’s applicable; Generally, global variables are applicable in situations when you’ve got an object / class of which you are only ever going to need one of them and they don’t logically sit as a child of one single part of the application. For instance, the ‘application’ object in some languages - where the object represents the running application.

So, Singleton Eh?

The Singleton model is often used to instantiate just one instance of a class which doesn’t allow a second instance of that same class to be loaded anywhere in the application. Some implementations will throw an exception if you try to create a second instance of the class, some will create the singleton for you when you first try to access it, and some will even let you create other instances if you want, but will always manage a ‘single shared instance’ for you. Many of the core Apple classes follow this pattern, such as [UIApplication sharedApplication].

Anyway, Apple do a very good job (naturally) of providing a good example of the Singleton model. The following code is rather similar to the Apple example, but it also includes what you should have in the header file. It is also a stable part of any library of code snippets, so it has to be here really!

SingletonClass.h

#import <Foundation/Foundation.h>

@interface SingletonClass : NSObject {

}

+ (id)sharedInstance;
@end

SingletonClass.m

#import "SingletonClass.h"

@implementation SingletonClass

static SingletonClass *sharedInstance = nil;

// Get the shared instance and create it if necessary.
+ (SingletonClass *)sharedInstance {
    if (sharedInstance == nil) {
        sharedInstance = [[super allocWithZone:NULL] init];
    }

    return sharedInstance;
}

// We can still have a regular init method, that will get called the first time the Singleton is used.
- (id)init
{
    self = [super init];

    if (self) {
        // Work your initialising magic here as you normally would
    }

    return self;
}

// Your dealloc method will never be called, as the singleton survives for the duration of your app.
// However, I like to include it so I know what memory I'm using (and incase, one day, I convert away from Singleton).
-(void)dealloc
{
    // I'm never called!
    [super dealloc];
}

// We don't want to allocate a new instance, so return the current one.
+ (id)allocWithZone:(NSZone*)zone {
    return [[self sharedInstance] retain];
}

// Equally, we don't want to generate multiple copies of the singleton.
- (id)copyWithZone:(NSZone *)zone {
    return self;
}

// Once again - do nothing, as we don't have a retain counter for this object.
- (id)retain {
    return self;
}

// Replace the retain counter so we can never release this object.
- (NSUInteger)retainCount {
    return NSUIntegerMax;
}

// This function is empty, as we don't want to let the user release this object.
- (oneway void)release {

}

//Do nothing, other than return the shared instance - as this is expected from autorelease.
- (id)autorelease {
    return self;
}

@end

There you go - copy and paste this into your new project, rename the interface and implementations and you’re done - a ready to use Singleton in your project.

Making the creation of your singleton thread safe

Jiunn Harr (site no longer exists) wrote a great blog post on making the creation of your Singleton thread safe. In the above example, it is possible that your Singleton’s init method could be called more than once, if sharedInstance was called for the first and second time concurrently on different threads. In order to by-pass this problem, you can replace the sharedInstance method above with the following;

+ (SingletonClass *)sharedInstance {
    if (nil != sharedInstance) {
        return sharedInstance;
    }

    static dispatch_once_t pred;        // Lock
    dispatch_once(&pred, ^{             // This code is called at most once per app
        singleton = [[SingletonClass alloc] init];
    });

    return singleton;
}

Note. This doesn’t make all calls on your Singleton thread safe - it simply ensures that the creation of your Singleton is thread safe. This code uses Grand Central Dispatch (Cocoa and iOS4+).

Using the Singleton Class

The above code creates the framework for a Singleton class. You can almost ignore the majority of the code above and no go about setting up your own variables and methods for use in your singleton class. It’s worth bearing in mind that when you first attempt to you access your Singleton, it will be created for you, and from that point onwards - it will probably reside in memory for the remainder of your application’s lifecycle. Because of this, you might want to be careful about memory usage and ensure that classes inside your singleton element are tidy.

Accessing your Singleton class from your code is then simply a matter of using the _+(SingletonClass*)sharedInstance_ to get a pointer to the one instance of the singleton class that exists in your application. You can do this anywhere in your code and you would do this for the above class by doing something like the following;

SingletonClass* sharedSingleton = [SingletonClass sharedInstance];
[sharedSingleton callAMethod];

Enjoy!