Sto cercando di elaborare un modello singleton appropriato per l'utilizzo in Swift. Finora, sono stato in grado di ottenere un modello non thread-safe funzionante come:
class var sharedInstance: TPScopeManager {
get {
struct Static {
static var instance: TPScopeManager? = nil
}
if !Static.instance {
Static.instance = TPScopeManager()
}
return Static.instance!
}
}
L'avvolgimento dell'istanza singleton nella struttura statica dovrebbe consentire una singola istanza che non si scontra con istanze singleton senza schemi di denominazione complessi e dovrebbe rendere le cose abbastanza private. Ovviamente, questo modello non è thread-safe. Quindi ho provato ad aggiungere dispatch_once
a tutto:
class var sharedInstance: TPScopeManager {
get {
struct Static {
static var instance: TPScopeManager? = nil
static var token: dispatch_once_t = 0
}
dispatch_once(Static.token) { Static.instance = TPScopeManager() }
return Static.instance!
}
}
Ma ottengo un errore del compilatore sulla dispatch_once
linea:
Impossibile convertire il tipo di espressione 'Void' in type '()'
Ho provato diverse varianti della sintassi, ma sembrano avere tutti gli stessi risultati:
dispatch_once(Static.token, { Static.instance = TPScopeManager() })
Qual è l'uso corretto dell'utilizzo di dispatch_once
Swift? Inizialmente pensavo che il problema fosse dovuto al blocco a causa del ()
messaggio di errore, ma più lo guardo, più penso che potrebbe essere una questione di ottenere il dispatch_once_t
definito correttamente.
@lazy
dovrebbe essere thread-safe.
Static.instance = TPScopeManager()
forza il tipo di istanza. Se usi qualcosa come Static.instance = self()
un inizializzatore richiesto, verrà generata la classe di tipo appropriata. Anche così, e questa è la cosa importante da notare, solo una volta per tutte le istanze nella gerarchia! Il primo tipo da inizializzare è il tipo impostato per tutte le istanze. Non credo che oggettivo c si sia comportato allo stesso modo.