Mit einem dispatch_once singleton-Modell in Swift

Ich bin versuchen zu arbeiten, eine entsprechende singleton-Modell für den Einsatz im Swift. Bisher habe ich in der Lage zu bekommen, eine non-thread-safe-Modell arbeiten:

class var sharedInstance:TPScopeManager {
    get {
        struct Static {
            static var instance : TPScopeManager? = nil
        }

        if !Static.instance {
            Static.instance = TPScopeManager()
        }

        return Static.instance!
    }
}

Verpackung die singleton-Instanz in der Statischen Struktur sollte es eine einzige Instanz, die nicht kollidieren mit singleton-Instanzen ohne komplexe Benennung schemings, und es sollten die Dinge ziemlich privat. Offensichtlich aber dieses Modell ist nicht thread-sicher, so habe ich versucht, hinzuzufügen dispatch_once zu der ganzen Sache:

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!
    }
}

Aber bekomme ich einen compiler-Fehler auf der dispatch_once Linie:

Nicht konvertieren kann der Ausdruck den Typ 'Void' zu geben '()'

Ich habe versucht, verschiedene Varianten der syntax, aber Sie alle scheinen die gleichen Ergebnisse:

dispatch_once(Static.token, { Static.instance = TPScopeManager() })

Was ist die richtige Verwendung von dispatch_once mit Swift? Anfänglich dachte ich, das problem mit dem block durch die () in der Fehlermeldung, aber je mehr ich schaue, desto mehr denke ich, dass es möglicherweise eine Frage der dispatch_once_t korrekt definiert ist.

Würde ich alle entfernen, die statische code und verwenden Sie eine readonly-Eigenschaft mit @lazy-Initialisierung.
Das ist es, was ich meinte. Leider haben wir immer noch nicht genug Informationen über die Interna. Jedoch, IMHO die Implementierung von @lazy sollte thread-sicher.
Und dieser Weg hat auch den Vorteil, dass keine Freilegung der Umsetzung der predations der Anrufer.
Es scheint auch gar nicht möchte, kann @lazy class-Variablen.
Seien Sie vorsichtig! Zwei Dinge zu beachten, die mit diesem Ansatz. Zuerst werden alle Klassen, die Erben, diese überschreiben die sharedInstance Eigenschaft. Static.instance = TPScopeManager() Kräfte des instance-Typs. Wenn Sie so etwas wie Static.instance = self() mit einer notwendigen Initialisierung der entsprechenden Typ-Klasse generiert werden. Auch so, und das ist die wichtige Sache zu beachten, nur einmal für alle Instanzen in der Hierarchie! Ersten Typs zu initialisieren, ist der Typ set für alle Instanzen. Ich glaube nicht, dass objective-c verhielten sich gleich.

InformationsquelleAutor David Berry | 2014-06-03

Schreibe einen Kommentar