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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…