Wie wird in der aktuellen Warteschlange versendet?

8

Nun, da dispatch_get_current_queue in iOS 6 veraltet ist, verwende ich dispatch_after , um etwas in der aktuellen Warteschlange auszuführen?

    
Boon 24.07.2013, 16:32
quelle

3 Antworten

5

Die verschiedenen Links in den Kommentaren sagen nicht "es ist besser, es nicht zu tun." Sie sagen, du kannst es nicht tun. Sie müssen entweder die gewünschte Warteschlange übergeben oder an eine bekannte Warteschlange senden. Dispatch-Warteschlangen haben nicht das Konzept von "aktuell". Blöcke füttern oft von einer Warteschlange in eine andere ("Targeting" genannt). Zu dem Zeitpunkt, an dem Sie tatsächlich laufen, ist die "aktuelle" Warteschlange nicht wirklich aussagekräftig, und wenn Sie sich darauf verlassen, kann dies (und historisch gesehen) zu einem Deadlock führen. dispatch_get_current_queue() war niemals zum Versenden gedacht; Es war eine Debugging-Methode. Deshalb wurde es entfernt (da die Leute es so behandelten, als ob es etwas Sinnvolles bedeute).

Wenn Sie diese Art der Buchführung auf höherer Ebene benötigen, verwenden Sie NSOperationQueue , das die ursprüngliche Warteschlange verfolgt (und ein einfacheres Warteschlangenmodell, das die ursprüngliche Warteschlange viel aussagekräftiger macht).

Es gibt verschiedene Ansätze, die in UIKit verwendet werden:

  • Übergeben Sie die Callback-Verteilungswarteschlange als Parameter (dies ist wahrscheinlich der gängigste Ansatz in neuen APIs). Siehe [NSURLConnection setDelegateQueue:] oder addObserverForName:object:queue:usingBlock: für Beispiele. Beachten Sie, dass NSURLConnection eine NSOperationQueue erwartet, nicht eine dispatch_queue . Übergeordnete APIs und all das.
  • Rufen Sie in der Warteschlange auf, in der Sie sich gerade befinden, und überlassen Sie es dem Empfänger, damit umzugehen. So haben Callbacks traditionell funktioniert.
  • Fordern Sie, dass ein Runloop für den aufrufenden Thread vorhanden ist, und planen Sie die Rückrufe für den aufrufenden Runloop. So arbeitete NSURLConnection in der Vergangenheit vor Warteschlangen.
  • Nehmen Sie Ihre Rückrufe immer an einer der bekannten Warteschlangen vor (insbesondere an der Hauptwarteschlange), sofern nicht anders angegeben. Ich weiß nirgendwo, dass dies in UIKit gemacht wird, aber ich habe es häufig im App-Code gesehen, und es ist die meiste Zeit ein sehr einfacher Ansatz.
Rob Napier 01.08.2013, 19:08
quelle
1

Erstellen Sie manuell eine Warteschlange und senden Sie sowohl Ihren aufrufenden Code als auch Ihren dispatch_after -Code dorthin. Auf diese Weise können Sie garantieren, dass beide Codeteile aus derselben Warteschlange ausgeführt werden.

    
Jurre 30.07.2013 21:30
quelle
0

Dies zu tun ist wahrscheinlich, weil die Notwendigkeit eines Hacks. Sie können dies mit einem anderen Hack hacken:

%Vor%

Anstelle von usleep() könnten Sie eine Schleife in einer Schleife verwenden.

Ich würde diesen "Ansatz" allerdings nicht empfehlen. Der bessere Weg besteht darin, eine Methode zu verwenden, die eine Warteschlange als Parameter und einen Block als Parameter akzeptiert, wobei der Block dann in der angegebenen Warteschlange ausgeführt wird.

Übrigens gibt es während der Ausführung eines Blocks verschiedene Möglichkeiten, um zu überprüfen, ob er in einer bestimmten Warteschlange bzw. in einer seiner übergeordneten Warteschlangen ausgeführt wird haben Sie zuvor einen Hinweis auf diese Warteschlange: Verwenden Sie die Funktionen dispatch_queue_set_specific und dispatch_get_specific .

    
CouchDeveloper 01.08.2013 18:30
quelle