Singleton in Objective-C/Swift

· 1 min read

What is behind the Singleton?

Singleton: Instantiation of a class to ONLY one object

Features of Singleton:

  1. One class only can have only one instance;
  2. It must can create this instance automatically;
  3. This instance must be provided to other objects.

Benefits of Singleton:

All objects can only have one instance. In other words, all the instances, no matter how they were created, they have the same memory address. In practise, we want singleton class to manage our database read/write, file IO, to make sure the data integrity.

There are three ways to create an instance:

Option 1. using alloc and init
Option 2. using static method. A way such as [UIApplication sharedApplication] to create a new instance.
Option 3. copying from an existing object

For example, create a custom class named Item, and implement its singleton method as:

In the code:

  • Remember copyWithZone method must be override when you want to do the copy on object
  • allocWithZone is called when you create an instance by alloc and init
  • When you are using multi-threading, singleton instance should be avoided created multiple times.

Another way for you to create a singleton is using use GCD:

#import "Item.h"

static id _instance;

@implementation Item

+ (id)allocWithZone:(struct _NSZone *)zone
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [super allocWithZone:zone];
    });
    return _instance;
}

+ (instancetype)sharedInstance
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [[self alloc] init];
    });
    return _instance;
    
    
}

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

@end

https://gist.github.com/arkilis/c3a51a4ef976ebda5c09cdfa33c5d6bd/

Updated: Singleton in Swift 2/3/4/5

class SingletonA {

    static let sharedInstance = SingletonA()

    init() {
        println("AAA");
    }

}

Updated in 2020: How to destroy a singleton object

In a recent project, I was trying to reload the whole application when a game is finished. (Yes, it is using the Spritekit!), and there is a need to manually dispose the singleton object while reloading. I tried many ways but find the following working pretty well:

class SoundManager: NSObject {
    
    struct Static {
        static var instance: SoundManager?
    }
    
    class var shared: SoundManager {
        if Static.instance == nil {
            Static.instance = SoundManager()
        }
        return Static.instance!
    }
}

Reference