Ich habe einen Rückruf, der von jedem Thread kommen könnte. Wenn ich diesen Rückruf erhalte, möchte ich eine bestimmte Aufgabe im Hauptthread ausführen.
Muss ich überprüfen, ob ich bereits im Haupt-Thread bin - oder gibt es eine Strafe, wenn ich diese Überprüfung nicht durchführe, bevor ich den folgenden Code aufrufe?
dispatch_async(dispatch_get_main_queue(), ^{
// do work here
});
Antworten:
Nein, Sie müssen nicht überprüfen, ob Sie bereits im Hauptthread sind. Wenn Sie den Block an die Hauptwarteschlange senden, planen Sie lediglich, dass der Block seriell im Hauptthread ausgeführt wird. Dies geschieht, wenn die entsprechende Ausführungsschleife ausgeführt wird.
Wenn Sie sich bereits im Hauptthread befinden, ist das Verhalten dasselbe: Der Block wird geplant und ausgeführt, wenn die Ausführungsschleife des Hauptthreads ausgeführt wird.
quelle
async
wieder in die Hauptwarteschlange zurückkehren, wird diese ausgeführt. Dies kann jedoch den erwarteten Zeitpunkt Ihrer Aktionen beeinträchtigen . Beispielsweise wird der UI-CodeviewDidLoad()
erst ausgeführt, nachdem die Ansicht zum ersten Mal angezeigt wurde .Für den oben beschriebenen asynchronen Versandfall sollten Sie nicht überprüfen müssen, ob Sie sich im Hauptthread befinden. Wie Bavarious angibt, wird dies einfach in die Warteschlange gestellt, um auf dem Hauptthread ausgeführt zu werden.
Wenn Sie jedoch versuchen, die oben genannten Schritte mit a
dispatch_sync()
auszuführen, und sich Ihr Rückruf im Hauptthread befindet, wird Ihre Anwendung an diesem Punkt blockiert. Ich beschreibe dies in meiner Antwort hier , weil mich dieses Verhalten beim Verschieben von Code überrascht hat-performSelectorOnMainThread:
. Wie ich dort erwähne, habe ich eine Hilfsfunktion erstellt:Dadurch wird ein Block synchron im Hauptthread ausgeführt, wenn sich die Methode, in der Sie sich befinden, derzeit nicht im Hauptthread befindet, und der Block wird nur inline ausgeführt, wenn dies der Fall ist. Sie können eine Syntax wie die folgende verwenden, um dies zu verwenden:
quelle
dispatch_set_specific()
dies in dem von Ihnen beschriebenen Fall hilfreich wäre: stackoverflow.com/a/12806754/19679 .Wie in den anderen Antworten erwähnt, ist dispatch_async vom Hauptthread in Ordnung.
Abhängig von Ihrem Anwendungsfall gibt es jedoch einen Nebeneffekt, den Sie möglicherweise als Nachteil betrachten: Da der Block in einer Warteschlange geplant ist, wird er erst ausgeführt, wenn die Steuerung zur Ausführungsschleife zurückkehrt, was zu einer Verzögerung führt die Ausführung Ihres Blocks.
Beispielsweise,
Wird ausgedruckt:
Aus diesem Grund würde dispatch_async Ihnen nicht helfen, wenn Sie erwarten würden, dass der Block zwischen den äußeren NSLogs ausgeführt wird.
quelle
Nein, Sie müssen nicht überprüfen, ob Sie sich im Haupt-Thread befinden. So können Sie dies in Swift tun:
Es ist als Standardfunktion in meinem Repo enthalten. Schauen Sie sich das an: https://github.com/goktugyil/EZSwiftExtensions
quelle