CFRunLoopPerformBlock vs. dispatch_async

8

Ich habe einige Berechnungen im Hintergrund-Thread, danach muss ich die Transformation einiger calayer aktualisieren, ich versuche

zu verwenden %Vor%

und

%Vor%

Ich dachte nur, sie sind gleich, aber ich fand die calayer funktionierte sehr glatt (vielleicht?), wenn Sie disass_async verwenden. Was ist der Unterschied zwischen diesen beiden Funktionen?

    
Tim 13.10.2012, 09:21
quelle

3 Antworten

13

Der Hauptunterschied besteht hier darin, dass CFRunLoopPerformBlock Ihnen erlaubt, bestimmte Lauf-Loop-Modi anzugeben, in denen der Block ausgeführt wird, während dispatch_async(dispatch_get_main_queue(),...) nur in allgemeinen Modi ausgeführt wird. Vielleicht hängt es mehr von dem Leistungsproblem ab, das Sie sehen, CFRunLoopPerformBlock macht nicht den Hauptthread aktiv. Aus der Dokumentation für CFRunLoopPerformBlock :

  

Diese Methode reiht den Block nur in die Warteschlange ein und wacht nicht automatisch auf   die angegebene Laufschleife. Daher erfolgt die Ausführung des Blocks die   Beim nächsten Mal wird die Laufschleife aktiviert, um eine andere Eingabequelle zu verarbeiten. Wenn du   Willst du die Arbeit sofort erledigen, musst du das explizit aufwecken   Thread mit der Funktion CFRunLoopWakeUp.

In der Praxis bedeutet dies normalerweise, dass Ihr Block erst ausgeführt wird, wenn die Laufschleife aufwacht (dh Benutzerereignis tritt auf, Timer wird ausgelöst, Schleifenquellen werden ausgelöst, Mach-Nachricht wird empfangen usw.). GCD ist nicht per Entwurf, eine Run-Loop-basierte API; Die Beziehung zwischen der Hauptwarteschlange und der Hauptthreadlaufschleife ist effektiv ein Implementierungsdetail. Ich würde erwarten, dass diese Implementierung die Ausführungsschleife selbst aufweckt, wenn dies für die Hauptwarteschlange erforderlich wäre.

Wenn keine gegenteiligen Informationen vorliegen, vermute ich, dass dies die Ursache für den Leistungsunterschied ist. Ich würde erwarten, dass die Leistung ähnlich ist, wenn Sie einen Aufruf von CFRunLoopWakeUp direkt nach Ihrem Aufruf an CFRunLoopPerformBlock hinzugefügt haben.

    
ipmcc 10.02.2013, 19:07
quelle
3

Die Hauptwarteschlange von GCD ist eine serielle Warteschlange. Es kann also nur eine Aufgabe gleichzeitig ausführen. Selbst wenn diese Task eine innere Ausführungsschleife ausführt, z. B. einen modalen Dialog ausführt, können andere Aufgaben, die an die Hauptwarteschlange übergeben werden, erst ausgeführt werden, wenn dies abgeschlossen ist.

Aufgaben, die mit CFRunLoopPerformBlock() übergeben wurden, können ausgeführt werden, wenn die Laufschleife in einem der Zielmodi ausgeführt wird. Dies gilt auch, wenn die Laufschleife von einer Task ausgeführt wird, die mit CFRunLoopPerformBlock() gesendet wurde.

Betrachten Sie die folgenden Beispiele:

%Vor%

erzeugt eine Ausgabe wie:

%Vor%

Währenddessen:

%Vor%

erzeugt:

%Vor%     
Ken Thomases 02.10.2014 22:49
quelle
1

Ich benutze sie manchmal zusammen:

%Vor%

Ich benutze dies, um einen Block an den Haupt-Thread zu senden, der ausgeführt wird, ohne "Störungen" zu verursachen, wenn ein UIScrollview scrollt.

Ich habe auch kürzlich verwendet:

%Vor%

anstelle von:

%Vor%

, um die Ausführung des Codes für den nächsten Durchlauf durch den Runloop zu verzögern. Auf diese Weise muss ich keine spezielle Methode erstellen, die den Code enthält, den ich ausführen möchte, und muss nicht alle Parameter zur Ausführung in ein einziges (id) myObject umwandeln.

    
hyperspasm 23.05.2014 00:36
quelle