it-swarm.com.de

Unterschied zwischen DispatchQueue.main.async und DispatchQueue.main.sync

Ich verwende DispatchQueue.main.async seit langer Zeit, um einige UI-bezogene Operationen durchzuführen. Aber Swift liefert DispatchQueue.main.async und DispatchQueue.main.sync und beide werden in der Hauptwarteschlange ausgeführt. Kann mir jemand einen Unterschied zwischen ihnen sagen? Und wann soll ich sie verwenden? Danke in voraus.

        DispatchQueue.main.async {
            self.imageView.image = imageView
            self.lbltitle.text = ""

        }
        DispatchQueue.main.sync {
            self.imageView.image = imageView
            self.lbltitle.text = ""

        }
70
Aman.Samghani

Warum Nebenläufigkeit? Sobald Sie Ihrer App schwere Aufgaben wie das Laden von Daten hinzufügen, verlangsamt Ihre Benutzeroberfläche die Arbeit oder friert sie sogar ein. Parallelität lässt Sie zwei oder mehr Aufgaben gleichzeitig ausführen. Der Nachteil dieses Ansatzes ist die nicht immer so einfach zu kontrollierende Fadensicherheit. F.e. Wenn verschiedene Tasks auf dieselben Ressourcen zugreifen möchten, z. B. wenn Sie versuchen, dieselbe Variable in einem anderen Thread zu ändern, oder wenn Sie auf Ressourcen zugreifen möchten, die bereits von den verschiedenen Threads blockiert wurden.

Es gibt ein paar Abstraktionen, auf die wir achten müssen.

  • Warteschlangen.
  • Synchrone/asynchrone Taskleistung.
  • Prioritäten.
  • Gemeinsame Probleme.

Queues .

Muss serial oder concurrent sein. Sowie global oder privat gleichzeitig.

Bei seriellen Warteschlangen werden die Aufgaben nacheinander abgeschlossen, während bei gleichzeitigen Warteschlangen die Aufgaben gleichzeitig ausgeführt und nach unerwarteten Zeitplänen erledigt werden. Dieselbe Aufgabengruppe benötigt in einer seriellen Warteschlange mehr Zeit als in einer gleichzeitigen Warteschlange.

Sie können Ihre eigenen privaten Warteschlangen erstellen (beide seriell oder gleichzeitig) oder bereits vorhandene global ( System) Warteschlangen. Die Hauptwarteschlange ist die einzige serielle Warteschlange aus allen globalen Warteschlangen.

Es wird dringend empfohlen, keine schweren Aufgaben, die sich nicht auf die Benutzeroberfläche beziehen, in der Hauptwarteschlange auszuführen (z. B. Laden von Daten aus dem Netzwerk), sondern diese in den anderen Warteschlangen auszuführen, um die Benutzeroberfläche nicht mehr eingefroren und reagiert auf Benutzeraktionen. Wenn wir die Benutzeroberfläche in den anderen Warteschlangen ändern lassen, können die Änderungen nach einem anderen und unerwarteten Zeitplan und mit einer anderen Geschwindigkeit vorgenommen werden. Einige Elemente der Benutzeroberfläche können vor oder nach ihrer Verwendung gezeichnet werden. Die Benutzeroberfläche kann abstürzen. Da es sich bei den globalen Warteschlangen um Systemwarteschlangen handelt, kann das System noch einige andere Aufgaben ausführen.


Dienstgüte/Priorität .

Warteschlangen haben auch verschiedene qos (Quality of Service) , wodurch die auszuführende Aufgabe festgelegt wird priority (hier von der höchsten zur niedrigsten):
. userInteractive - Hauptwarteschlange
. userInitiated - für den Benutzer initiierte Aufgaben, bei denen der Benutzer auf eine Antwort wartet
. utility - für Aufgaben, die einige Zeit in Anspruch nehmen und keine sofortige Reaktion erfordern, z. B. das Arbeiten mit Daten
. background - für Aufgaben, die nicht mit dem visuellen Teil zusammenhängen und die für die Abschlusszeit nicht streng sind).

Es gibt auch

. default Warteschlange, die die qos Informationen nicht überträgt. Wenn es nicht möglich war, die qos zu erkennen, werden die qos zwischen . UserInitiated und .utility.

Aufgaben können ausgeführt werden synchron oder asynchron .

  • Die Funktion Synchronous gibt die Steuerung erst an die aktuelle Warteschlange zurück, nachdem die Aufgabe abgeschlossen wurde. Es blockiert die Warteschlange und wartet, bis die Aufgabe beendet ist.

  • Die Funktion Asynchronous gibt die Steuerung an die aktuelle Warteschlange zurück, unmittelbar nachdem eine Aufgabe gesendet wurde, die in der anderen Warteschlange ausgeführt werden soll. Es wartet nicht, bis die Aufgabe beendet ist. Die Warteschlange wird nicht blockiert.

Häufige Probleme.

Die häufigsten Fehler, die Programmierer beim Projizieren der gleichzeitigen Apps machen, sind die folgenden:

  • Race condition - Wird verursacht, wenn die App-Arbeit von der Reihenfolge der Ausführung der Codeteile abhängt.
  • Prioritätsumkehr - wenn die Aufgaben mit höherer Priorität darauf warten, dass die Aufgaben mit niedrigerer Priorität abgeschlossen werden, weil einige Ressourcen blockiert sind
  • Deadlock - wenn einige Warteschlangen unendlich lange auf die Quellen (Variablen, Daten usw.) warten, die bereits von einigen dieser Warteschlangen blockiert wurden.

NIEMALS die Synchronisierungsfunktion in der Hauptwarteschlange aufrufen .
Wenn Sie die Synchronisierungsfunktion in der Hauptwarteschlange aufrufen, wird die Warteschlange blockiert, und die Warteschlange wartet darauf, dass die Aufgabe erledigt wird. Die Aufgabe wird jedoch niemals beendet, da sie nicht einmal gestartet werden kann wegen der Warteschlange ist bereits gesperrt. Es heißt Deadlock .

Wann soll Sync verwendet werden? Wann müssen wir warten, bis die Aufgabe abgeschlossen ist. F.e. wenn wir sicherstellen, dass eine Funktion/Methode nicht doppelt aufgerufen wird. F.e. Wir haben eine 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 Absturz verursacht hat? IOS Gerät?

125
Alexander

Wenn Sie async verwenden, wird die aufrufende Warteschlange fortgesetzt, ohne dass gewartet werden muss, bis der verteilte Block ausgeführt wird. Im Gegensatz dazu stoppt sync die aufrufende Warteschlange und wartet, bis die von Ihnen im Block gesendete Arbeit erledigt ist. Daher kann sync zu Deadlocks führen. Versuchen Sie es mit DispatchQueue.main.sync aus der Hauptwarteschlange und die App wird eingefroren, weil die aufrufende Warteschlange wartet, bis der gesendete Block beendet ist, aber nicht einmal gestartet werden kann (weil die Warteschlange angehalten wurde und wartet)

Wann benutzt man sync? Wenn Sie auf etwas warten müssen, das in einer VERSCHIEDENEN Warteschlange erledigt ist, und erst dann weiter an Ihrer aktuellen Warteschlange arbeiten müssen

Beispiel für die Verwendung der Synchronisierung:

In einer seriellen Warteschlange können Sie sync als Mutex verwenden, um sicherzustellen, dass nur ein Thread gleichzeitig den geschützten Code ausführen kann.

22