What is behind the Singleton?
Singleton: Instantiation of a class to ONLY one object
Features of Singleton:
- One class only can have only one instance;
- It must can create this instance automatically;
- 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 byalloc
andinit
- 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!
}
}