Wie ändern Sie die Priorität eines benutzerdefinierten GCD Warteschlange?
Habe ich einen GCD Warteschlange wie diese:
dispatch_queue_t q = dispatch_queue_create("com.testcompany.myqueue", NULL);
Wenn ich Versand der Aufgaben an die Warteschlange, es ist irgendwie langsamer als einfach Ausführung der Aufgabe auf dem Haupt-thread.
dispatch_async(q, ^(void) {
[self performHeavyCalculationAndUpdateUI];
});
Mein Verdacht ist, dass das queue hat eine sehr niedrige Priorität von Standard.
Wie kann ich die Priorität ändern, die von dieser Warteschlange? Oder ist es etwas anderes was ich tun muss?
- UIKit definitiv hat NICHT werden Sie threadsicher sind in iOS 4. Wo auf der Erde wolltest du das hören??
- Sie sagte, dass auf der WWDC. Ich bin mir 60% sicher.
- Ich bin mir 100% sicher, dass Sie das gar nicht. Es ist nie sicher, ändern Sie Ihre Benutzeroberfläche aus beliebigen anderen Threads als dem Hauptthread.
- Teile des UIKit wurde thread-sicher (begrenzt). Aus den developer notes hier: developer.apple.com/library/ios/#releasenotes/General/... "Zeichnen auf einem Grafik-Kontext, in UIKit ist jetzt thread-sicher."
- fair genug, obwohl die Zeichnung in einem Kontext ≠ Sie die Benutzeroberfläche ändern
- Ja, natürlich. Ich bin nur darauf hin, was OP wahrscheinlich eigentlich gehört (und anschließend falsch interpretiert) auf der WWDC.
- Es stellt sich heraus, können Sie zum ändern der Priorität eines seriellen queue - danke an Mike Asche für die Antwort. Zum Beispiel, um myqueue Ausführung im hintergrund Priorität verwenden dispatch_set_target_queue(myqueue, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0))
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn du tust UIKit Zeug, in Ihrem block, der ausgeführt wird, auf die sekundäre Warteschlange, Versand der UI-updates zurück auf die Haupt-Warteschlange aus, in die sekundäre Warteschlange über:
Versand nur die paar Zeilen, die eigentlich die Aktualisierung der Benutzeroberfläche zurück an den Haupt-Warteschlange und Sie werden sehen, es ist nicht eine Frage der Warteschlange Prioritäten, sondern nur sicherstellen, dass die Aktualisierung der Benutzeroberfläche geschehen, in der main queue.
addSubview
) zu den wichtigsten Warteschlange. Wenn Ihr das ändern der Eigenschaften der Elemente sind bereits in der Ansicht, ich würde denken, dass Sie müssten zu versenden Sie diese updates auf der main queue.Dispatch-queues nicht über eine Priorität, die Sie ändern können.
Können Sie ändern Sie die target queue des seriellen queues über die
dispatch_set_target_queue
Funktionen und verwenden Sie dieDISPATCH_QUEUE_PRIORITY_HIGH
globalen Warteschlange. Dies nur sichergestellt, dass es geplant wird, bevor andere Blöcke eingereiht, die auf den Warteschlangen mit dem Standard-oder low priority. Sobald Ihr block beginnt mit der Ausführung, es wird nicht schneller oder langsamer ablaufen, egal was Warteschlange war es geplant.Dein problem ist höchstwahrscheinlich die Aktualisierung der GUI, siehe Robert Ryans Antwort.
Ich denke, Sie sind fehlt den Punkt der asynchronen Aktivitäten. Und @RobertRyan Kommentar über die Aktualisierung der Benutzeroberfläche zeigt nicht schnell, wenn durchgeführt, auf sekundären Warteschlangen ist falsch. Alle UI-updates durchgeführt werden müssen, um auf das Haupt-queue. Zeitraum.
Aber zurück zum GCD und die asynchrone queue. @Sven richtig, dass Sie können nicht ändern die Priorität der dispatch-queues. Warteschlangen im GCD Arbeit in einem FIFO - (First In First Out) Mode, also die Reihenfolge, die Sie Sie Schlange ist der Auftrag, den Sie bekommen durchgeführt. Dies ist ein Teil, warum mit GCD ist thread-sicher; du bist garantiert du wirst nicht in Probleme, weil dieser FIFO-Warteschlange Priorität. Die zweite Sache, die Sie verstehen müssen, ist, dass, wenn Sie dispatch_async eine Warteschlange, die OS bietet keine Garantie an, wenn diese Warteschlange verarbeitet werden. Es ist ein Satz es und vergessen es Art von Prozess. Wenn Sie brauchen, um zu wissen, Wann der Warteschlange erfolgt die Verarbeitung, die Sie benötigen, um eine Abschluss-block-handler (Sie werden bemerken, dass viele von Apple ' s Frameworks haben begonnen, dies umzusetzen) zu verständigen. Dies ist der Grund, warum Apple schlägt verschachteln einer dispatch_async rufen Sie in Ihrem ersten dispatch_async anrufen und anfordern der Haupt-thread für die Aktualisierung der Benutzeroberfläche. Also, würde der code wie folgt Aussehen:
Weil, wie GCD reiht und aus der Warteschlange entfernt, die Verteilung der UI-updates asyncronously zurück in die main queue wird es ermöglichen, die UI-updates zu kommen, ohne eine wahrnehmbare Verzögerung für den Benutzer. Wenn Ihre UI-updates abhängig vom Ergebnis der performHeavyCalculations, Sie müssen eine Abschluss-handler oder delegation-Schema zur Benachrichtigung des Haupt-Warteschlange, wenn dieser abgeschlossen ist, so dass die Aktualisierungen die auftreten können. Wenn die lag zwischen den Berechnungen und das update ist zu lang, müssen Sie möglicherweise Einblick in das, was Sie tun, in die Berechnungen Methode, die so lange gedauert hat.
performHeavyCalculations
, und nach Abschluss in die Warteschlange, es reiht die UI-update-block auf der Haupt-queue. Das UI-update-block nicht passieren, bisperformHeavyCalculations
abgeschlossen ist. Hoffe, dass klärt die Dinge.performHeavyCalculations
könnte reflektieren UI updates mit mehr unmittelbares feedback ", wenn diese Methode löst die Aktualisierung der Benutzeroberfläche zurück auf die Haupt-queue." Als ich dies schrieb, gab es eine Flut von verwirrenden SO anderen Diskussionen über die Einordnung von UI-updates und hintergrund-Warteschlangen. Aber du hast ganz Recht, wie geschrieben, die UI-updates sind nicht immer vorgelegt, bis nachperformHeavyCalculations
fertig ist (vorausgesetzt, es ist nicht etwas seltsam, wie die Einreichung von Aufgaben asynchron, noch eine andere Warteschlange). Ich entschuldige mich, dass ich war nicht sehr klar in diesem Punkt.