Ich habe DispatchQueue.main.async
für eine lange Zeit verwendet, um UI-bezogene Operationen durchzuführen.
Swift stellt beide DispatchQueue.main.async
und zur Verfügung DispatchQueue.main.sync
, und beide werden in der Hauptwarteschlange ausgeführt.
Kann mir jemand den Unterschied zwischen ihnen sagen? Wann sollte ich jeden verwenden?
DispatchQueue.main.async {
self.imageView.image = imageView
self.lbltitle.text = ""
}
DispatchQueue.main.sync {
self.imageView.image = imageView
self.lbltitle.text = ""
}
quelle
DispatchQueue.main.sync
von einem Hintergrund-Thread aus aufzurufen ?async
dort anrufen würden. Ich meine, da es danach nichts mehr auf dem Thread gibt, macht es keinen Unterschied. Wenn esDispatchQueue.main.sync {block1}; DispatchQueue.main.sync {block2};
so wäre, hätte es Sinn gemacht. Aber wenn es keinen anderen Block gibt, kann ich mir den Vorteil der Verwendung vonDispatchQueue.main.sync {Oneblock}
over nicht vorstellenDispatchQueue.main.async {Oneblock}
. Für beide erhalten sie die mainQueue-Priorität / Unmittelbarkeit und nichts würde sie unterbrechen.Warum Parallelität?
Sobald Sie Ihrer App schwere Aufgaben wie das Laden von Daten hinzufügen, verlangsamt dies Ihre UI-Arbeit oder friert sie sogar ein. Mit Parallelität können Sie zwei oder mehr Aufgaben „gleichzeitig“ ausführen. Der Nachteil dieses Ansatzes ist die Gewindesicherheit, die nicht immer so einfach zu kontrollieren ist. Zum Beispiel, wenn verschiedene Aufgaben auf dieselben Ressourcen zugreifen möchten, z. B. der Versuch, dieselbe Variable in einem anderen Thread zu ändern oder auf die Ressourcen zuzugreifen, die bereits von den verschiedenen Threads blockiert wurden.
Es gibt einige Abstraktionen, die wir beachten müssen.
Warteschlangen
Muss seriell oder gleichzeitig sein . Sowie global oder privat zugleich.
Bei seriellen Warteschlangen werden Aufgaben einzeln erledigt, während bei gleichzeitigen Warteschlangen Aufgaben gleichzeitig ausgeführt und nach unerwarteten Zeitplänen ausgeführt werden. Dieselbe Gruppe von Aufgaben benötigt in einer seriellen Warteschlange mehr Zeit als in einer gleichzeitigen Warteschlange.
Sie können Ihre eigenen privaten Warteschlangen (sowohl seriell als auch gleichzeitig ) erstellen oder bereits verfügbare globale (System-) Warteschlangen verwenden . Die Hauptwarteschlange ist die einzige serielle Warteschlange aller globalen Warteschlangen .
Es wird dringend empfohlen, keine schweren Aufgaben auszuführen, die nicht als UI-Arbeit in der Hauptwarteschlange bezeichnet werden (z. B. Laden von Daten aus dem Netzwerk), sondern in den anderen Warteschlangen, um die Benutzeroberfläche nicht eingefroren zu halten und auf die Benutzeraktionen zu reagieren. Wenn wir die Benutzeroberfläche in den anderen Warteschlangen ändern lassen, können die Änderungen nach einem anderen und unerwarteten Zeitplan und einer anderen Geschwindigkeit vorgenommen werden. Einige UI-Elemente können vor oder nach ihrer Verwendung gezeichnet werden. Es kann die Benutzeroberfläche zum Absturz bringen. Da es sich bei den globalen Warteschlangen um Systemwarteschlangen handelt, müssen einige andere Aufgaben vom System ausgeführt werden.
Servicequalität / Priorität
Warteschlangen haben auch unterschiedliche QOS (Quality of Service), die die Priorität für die Ausführung der Aufgabe festlegen ( hier von der höchsten zur niedrigsten):
.userInteractive - Hauptwarteschlange
.userInitiated - für vom Benutzer initiierte Aufgaben, bei denen der Benutzer auf eine Antwort wartet
.utility - für die Aufgaben
Dies dauert einige Zeit und erfordert keine sofortige Reaktion, z. B. Arbeiten mit Daten. Hintergrund - für Aufgaben, die nicht mit dem visuellen Teil zusammenhängen und für die Fertigstellungszeit nicht streng sind.
Es gibt auch eine
Standardwarteschlange, die die QOS- Informationen nicht überträgt . Wenn es nicht möglich war, die QOS zu erkennen dieqos wird zwischen .userInitiated und .utility verwendet .
Aufgaben können synchron oder asynchron ausgeführt werden .
Die synchrone Funktion gibt die Steuerung erst nach Abschluss der Aufgabe an die aktuelle Warteschlange zurück. Es blockiert die Warteschlange und wartet, bis die Aufgabe beendet ist.
Die asynchrone Funktion gibt die Steuerung direkt nach dem Senden der Aufgabe an die aktuelle Warteschlange zurück, um sie in der anderen Warteschlange auszuführen. Es wartet nicht, bis die Aufgabe beendet ist. Die Warteschlange wird nicht blockiert.
Häufige Probleme.
Die beliebtesten Fehler, die Programmierer beim Projizieren der gleichzeitigen Apps machen, sind folgende:
Rufen Sie NIEMALS die Synchronisierungsfunktion in der Hauptwarteschlange auf .
Wenn Sie die Synchronisierungsfunktion in der Hauptwarteschlange aufrufen, wird die Warteschlange blockiert, und die Warteschlange wartet auf den Abschluss der Aufgabe. Die Aufgabe wird jedoch nie beendet, da sie aufgrund der Warteschlange nicht einmal gestartet werden kann bereits gesperrt. Es heißt Deadlock .
Wann soll die Synchronisierung verwendet werden? Wenn wir warten müssen, bis die Aufgabe erledigt ist. Fe, wenn wir sicherstellen, dass eine Funktion / Methode nicht doppelt aufgerufen wird. Fe wir haben Synchronisation und versuchen zu verhindern, dass es doppelt aufgerufen wird, bis es vollständig fertig ist. Hier ist ein Code für dieses Problem:
Wie kann man herausfinden, was einen Fehler-Absturzbericht auf dem IOS-Gerät verursacht hat?
quelle
DispatchQueue.main.sync
von einem Hintergrund-Thread aus aufzurufen ?sync
oderasync
Methoden haben keine Auswirkung auf die Warteschlange, in der sie aufgerufen werden.sync
blockiert den Thread, von dem aus er aufgerufen wird, und nicht die Warteschlange, in der er aufgerufen wird. Es ist die Eigenschaft,DispatchQueue
die entscheidet, ob derDispatchQueue
Benutzer auf die Ausführung der Aufgabe wartet (serielle Warteschlange) oder die nächste Aufgabe ausführen kann, bevor die aktuelle Aufgabe abgeschlossen ist (gleichzeitige Warteschlange).Selbst wenn
DispatchQueue.main.async
es sich um einen asynchronen Aufruf handelt, kann eine hinzugefügte Hochleistungsoperation die Benutzeroberfläche einfrieren, da ihre Operationen seriell auf dem Hauptthread ausgeführt werden. Wenn diese Methode vom Hintergrund-Thread aufgerufen wird, kehrt die Steuerung sofort zu diesem Thread zurück, selbst wenn die Benutzeroberfläche eingefroren zu sein scheint. Dies liegt daran, dass derasync
Anruf aktiviert istDispatchQueue.main
quelle
GCD
ermöglicht es Ihnen, eine Aufgabe auszuführensynchronously
oderasynchronously
[Info] [Mehr]synchronous
Die Funktion (Blockieren und Warten) gibt eine Steuerung zurück, wann die Aufgabe abgeschlossen istasynchronous
Die Funktion (Versand und Fortfahren) gibt sofort ein Steuerelement zurück, das die Aufgabe zum Starten in eine entsprechende Warteschlange sendet, aber nicht darauf wartet, dass sie abgeschlossen wird.quelle