Are the two approaches the same or are there major differences/pitfalls to be aware of:
class MyClassSingleton {
static let sharedInstance = MyClassSinglet
That depends on what you want to achieve and how you want to use your structure based on differences between class
and struct
. Most common thing that you will see is using class with singleton object.
Singletons are pretty much the same, they are only created once, but you will get different behaviors from the class
and from struct
because:
There are several more differences but you get the idea from this.
The main difference is that class-based mutable singleton works, while struct-based mutable "singleton" doesn't. Unless you want to make your singleton immutable (which is rare) you should stick to the class-based one.
Here is an illustration of how mutable struct-based "singleton" does not work. Consider adding a mutable member state
to both singletons, like this:
class MyClassSingleton {
static let sharedInstance = MyClassSingleton()
private init(){}
var state = 5
func helloClass() { print("hello from class Singleton: \(state)") }
}
struct MyStructSingleton {
static let sharedInstance = MyStructSingleton()
private init() {}
var state = 5
func helloStruct() { print("hello from struct Singleton: \(state)") }
}
I made state
a var
, but I could expose it as a read-only property plus a mutating method; the essential thing is that both types are now mutable.
If I do this
let csi = MyClassSingleton.sharedInstance
csi.state = 42
MyClassSingleton.sharedInstance.helloClass()
42 gets printed, because csi
is referencing the shared instance.
However, when I do the same thing with struct-based singleton
var ssi = MyStructSingleton.sharedInstance
ssi.state = 42
MyStructSingleton.sharedInstance.helloStruct()
5 gets printed instead, because ssi
is a copy of the sharedInstance
, which is, of course, an indication that our singleton is not actually a singleton.