Główna różnica polega na tym, że mutant działający w oparciu o klasy działa w oparciu o klasy, podczas gdy oparty na strukturze "singleton" nie działa. Jeśli nie chcesz, aby twój singleton był niezmienny (co jest rzadkością), powinieneś trzymać się klasy opartej na klasach.
Oto ilustracja tego, jak mutable "singleton" oparte na strukturze nie działa. Rozważyć dodanie zmienny element state
się zarówno pojedynczych, jak to:
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)") }
}
zrobiłem state
var
, ale mogę wystawiać go jako właściwość tylko do odczytu plus metody mutowania; najważniejsze jest to, że oba typy są teraz zmienne.
Jeśli mogę to zrobić
let csi = MyClassSingleton.sharedInstance
csi.state = 42
MyClassSingleton.sharedInstance.helloClass()
42 zostanie wydrukowany, ponieważ csi
odwołuje udostępnionego instancji.
Jednak, gdy robię to samo z struct oparte Singleton
var ssi = MyStructSingleton.sharedInstance
ssi.state = 42
MyStructSingleton.sharedInstance.helloStruct()
5 zostanie wydrukowany zamiast, ponieważ ssi
jest kopia sharedInstance
, co jest, oczywiście, wskazanie, że nasza Singleton właściwie nie singleton.
Co ciekawe, użycie 'static var sharedInstance' zamiast' static let sharedInstance' sprawia, że wydaje się działać. Czy nowa kopia struktury jest generowana za każdym razem, gdy nazywam 'MyStructSingleton.sharedInstance'? –
@RunningTurtle Nowa kopia 'MyStructSingleton' jest tworzona po zadeklarowaniu nowej zmiennej typu' MyStructSingleton'. Po przypisaniu do niego parametru "sharedInstance" obie stają się identyczne, ale nie są to te same instancje. To samo dzieje się, gdy przekazujesz 'MyStructSingleton' jako parametr lub zwracasz go z metody. – dasblinkenlight