What's the difference between Struct based and Class based singletons?
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.
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:
- Classes are reference types, while structs are value types
- Structs are used to define simple structures
- Structs can't be inherited
There are several more differences but you get the idea from this.