J'essaie de trouver un modèle singleton approprié à utiliser dans Swift. Jusqu'à présent, j'ai pu obtenir un modèle non thread-safe fonctionnant comme:
class var sharedInstance: TPScopeManager {
get {
struct Static {
static var instance: TPScopeManager? = nil
}
if !Static.instance {
Static.instance = TPScopeManager()
}
return Static.instance!
}
}
L'encapsulation de l'instance singleton dans la structure statique devrait permettre une seule instance qui n'entre pas en collision avec des instances singleton sans schémas de nommage complexes, et devrait rendre les choses assez privées. Évidemment, ce modèle n'est pas thread-safe. J'ai donc essayé d'ajouter dispatch_once
à tout cela:
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!
}
}
Mais j'obtiens une erreur de compilation sur la dispatch_once
ligne:
Impossible de convertir le type de l'expression 'Void' en type '()'
J'ai essayé plusieurs variantes différentes de la syntaxe, mais elles semblent toutes avoir les mêmes résultats:
dispatch_once(Static.token, { Static.instance = TPScopeManager() })
Quelle est la bonne utilisation de dispatch_once
Swift? Au début, je pensais que le problème était avec le bloc en raison du ()
message d'erreur, mais plus je le regarde, plus je pense qu'il peut être question d'obtenir le dispatch_once_t
correctement défini.
@lazy
devrait être thread-safe.
Static.instance = TPScopeManager()
force le type d'instance. Si vous utilisez quelque chose comme Static.instance = self()
avec un initialiseur requis, la classe de type appropriée sera générée. Même ainsi, et c'est la chose importante à noter, une seule fois pour toutes les instances de la hiérarchie! Le premier type à initialiser est le type défini pour toutes les instances. Je ne pense pas que l'objectif-c se soit comporté de la même façon.