Singletons are fairly easy in Swift. A singleton is an object of which there can never be more than one instance in your program. The first instance of a singleton object will be the last. As a corollary, singletons never die, and their lifespan is always your whole program.
In Swift, we have to be particularly cautious about retain cycles. Any object that will be retained by your singleton will ultimately live till the end of your program. It's not an understatement to say: you have to be very cautious with them.
Here's an example:
class Earth {
static let current = Earth()
private init() {}
func spinAroundTheSun() { /* */ }
}
let planetEarth = Earth.instance
planetEarth.spinAroundTheSun()
Here, we have an Earth class. There is only one Earth (as far as we know), so it's safe to assume that we can use the singleton pattern to represent that, through static let current = Earth().
The initializer is also marked as private—this way we prevent accidental initialization of additional Earths.
You may remember the good old Objective-C singleton syntax, as follows:
@implementation Earth
+ (id)currentEarth {
static Earth *sharedEarth = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedEarth;
}
@end
You may wonder why it is not necessary to write an exact translation of that code block in Swift. The reason is quite simple—the compiler does it for us.
In Objective-C, there were two main features of this static + (id)currentEarth method:
- It is thread-safe, as dispatch_once is thread-safe
- It is lazy, as static Earth *sharedEarth is nil until there's a call to currentEarth
Those two features are handled for us by the compiler! So worry not, using static let shared = Earth() is as safe and as performant as the good old Objective-C code.