Was ist die neue Syntax dispatch_once
in Swift nach den Änderungen in Sprachversion 3? Die alte Version war wie folgt.
var token: dispatch_once_t = 0
func test() {
dispatch_once(&token) {
}
}
Dies sind die Änderungen an libdispatch , die vorgenommen wurden.
pod 'SwiftDispatchOnce', '~> 1.0'
Prost. :]Antworten:
Aus dem Dokument :
quelle
dispatch_once
war klar. Dies ist leider hässlich und verwirrend ..Während die Verwendung von verzögert initialisierten Globals für eine einmalige Initialisierung sinnvoll sein kann, ist sie für andere Typen nicht sinnvoll. Es ist sehr sinnvoll, faul initialisierte Globals für Dinge wie Singletons zu verwenden. Es ist nicht sehr sinnvoll für Dinge wie das Bewachen eines Swizzle-Setups.
Hier ist eine Swift 3-Implementierung von dispatch_once:
Hier ist ein Anwendungsbeispiel:
oder mit einer UUID
Da wir uns derzeit in einer Zeit des Übergangs von Swift 2 zu 3 befinden, ist hier ein Beispiel für die Implementierung von Swift 2:
quelle
objc_sync_enter
undobjc_sync_exit
.Als Erweiterung der obigen Antwort von Tod Cunningham habe ich eine weitere Methode hinzugefügt, mit der das Token automatisch aus Datei, Funktion und Zeile erstellt wird.
So kann es einfacher sein, Folgendes anzurufen:
und Sie können immer noch ein Token angeben, wenn Sie möchten:
Ich nehme an, Sie könnten eine Kollision bekommen, wenn Sie dieselbe Datei in zwei Modulen haben. Schade, dass es das nicht gibt
#module
quelle
Bearbeiten
Antwort von @ Frizlab - Diese Lösung ist nicht garantiert threadsicher. Eine Alternative sollte verwendet werden, wenn dies entscheidend ist
Einfache Lösung ist
verwendet wie
quelle
Sie können es weiterhin verwenden, wenn Sie einen Bridging-Header hinzufügen:
Dann
.m
irgendwo:Sie sollten jetzt in der Lage sein,
mxcl_dispatch_once
von Swift zu verwenden.Meistens sollten Sie stattdessen das verwenden, was Apple vorschlägt, aber ich hatte einige legitime Verwendungszwecke, bei denen ich
dispatch_once
mit einem einzigen Token in zwei Funktionen arbeiten musste, und es wird nicht abgedeckt, was Apple stattdessen bereitstellt.quelle
Sie können eine Variablenfunktion der obersten Ebene wie folgt deklarieren:
dann nenne das irgendwo:
quelle
Swift 3: Für diejenigen, die wiederverwendbare Klassen (oder Strukturen) mögen:
Verwendung:
Update (28. April 2017):
OSSpinLock
Ersetzt durchos_unfair_lock
fällige Verfallswarnungen in macOS SDK 10.12.quelle
OSSpinLock
ersetzt durchos_unfair_lock
. Übrigens: Hier ist ein gutes WWDC-Video überConcurrent Programming
: developer.apple.com/videos/play/wwdc2016/720Ich verbessere die obigen Antworten und erhalte das Ergebnis:
quelle
Verwenden Sie den Klassenkonstantenansatz, wenn Sie Swift 1.2 oder höher verwenden, und den verschachtelten Strukturansatz, wenn Sie frühere Versionen unterstützen müssen. Eine Untersuchung des Singleton-Musters in Swift. Alle folgenden Ansätze unterstützen eine verzögerte Initialisierung und Thread-Sicherheit. Der dispatch_once-Ansatz funktioniert in Swift 3.0 nicht
Ansatz A: Klassenkonstante
Ansatz B: Verschachtelte Struktur
Ansatz C: dispatch_once
quelle