La differenza principale è che il singleton mutabile basato su classi funziona, mentre il "singleton" mutabile basato su struct non lo fa. A meno che tu non voglia rendere il tuo singleton immutabile (cosa rara) dovresti attenersi a quello basato sulla classe.
Ecco un'illustrazione di come "singleton" mutevole basato su struct non funziona. Considerare l'aggiunta di un membro mutabile state
ad entrambi single, in questo modo:
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)") }
}
Ho fatto un state
var
, ma ho potuto esporre come una proprietà di sola lettura più un metodo di mutante; la cosa essenziale è che entrambi i tipi sono ora mutabili.
Se faccio questo
let csi = MyClassSingleton.sharedInstance
csi.state = 42
MyClassSingleton.sharedInstance.helloClass()
42 viene stampato, perché csi
fa riferimento l'istanza condivisa.
Tuttavia, quando faccio la stessa cosa con struct a base di Singleton
var ssi = MyStructSingleton.sharedInstance
ssi.state = 42
MyStructSingleton.sharedInstance.helloStruct()
5 viene stampato, invece, a causa ssi
è una copia del sharedInstance
, che è, ovviamente, l'indicazione che il nostro Singleton è non in realtà un singleton.
interessante, usando 'static var sharedInstance' invece di' static let sharedInstance' fa sembrare che funzioni. Una nuova copia della struct è generata ogni volta che chiamo 'MyStructSingleton.sharedInstance'? –
@RunningTurtle Una nuova copia di 'MyStructSingleton' viene creata quando si dichiara una nuova variabile di tipo' MyStructSingleton'. Dopo aver assegnato 'sharedInstance' ad esso, i due diventano identici, ma non sono la stessa istanza. La stessa cosa accade quando si passa 'MyStructSingleton' come parametro o lo si restituisce da un metodo. – dasblinkenlight