Wie "dispatch_apply ()" zu brechen?

7

Gibt es eine Möglichkeit, eine break -Anweisung in einer dispatch_apply() blockieren?

ZB hat jede Cocoa-API, die ich mit Aufzählungsblöcken zu tun habe, einen "Stop" -Parameter:

%Vor%

Gibt es etwas Ähnliches für GCD?

    
Michael 23.06.2010, 21:09
quelle

3 Antworten

14

Vom Design her haben dispatch_*() APIs keine Auslöschung. Der Grund dafür ist, dass es fast allgemein wahr ist, dass Ihr Code das Konzept des Stoppens beibehält oder nicht, und somit auch unterstützt, dass in den Dispatch _ * () APIs redundant wäre (und bei Redundanz kommt es zu Fehlern) / p>

Wenn Sie also die ausstehenden Elemente in einer Dispatch-Warteschlange (unabhängig davon, wie sie in die Warteschlange eingereiht wurden) vorzeitig stoppen oder auf andere Weise abbrechen möchten, verwenden Sie dazu ein beliebiges Statusbit mit den Blöcken in der Warteschlange, die Sie abbrechen können .

%Vor%

Oder:

%Vor%

Beachten Sie, dass sowohl enumerateObjectsUsingBlock: als auch enumerateObjectsWithOptions:usingBlock: beide die Löschung unterstützen, da sich diese API in einer anderen Rolle befindet. Der Aufruf der Aufzählungsmethode ist synchron , auch wenn die tatsächliche Ausführung der Aufzählungsblöcke abhängig von den Optionen vollständig gleichzeitig erfolgen kann.

Das Setzen von *stopFlag=YES veranlasst also die Enumeration anzuhalten. Es garantiert jedoch nicht, dass es im gleichzeitigen Fall sofort aufhört. Die Enumeration kann in der Tat einige weitere bereits eingereihte Blöcke ausführen, bevor sie stoppt.

(Man könnte kurz annehmen, dass es sinnvoller ist, BOOL zurückzugeben, um anzugeben, ob die Enumeration fortgesetzt werden soll. Dies hätte zur Folge, dass der Enumerationsblock synchron ausgeführt werden müsste, auch im Parallelfall, so dass die Rückgabe erfolgt Wert könnte überprüft werden. Dies wäre erheblich weniger effizient gewesen.)

    
bbum 23.06.2010 23:25
quelle
4

Ich denke nicht, dass dispatch_apply dies unterstützt. Der beste Weg, um es nachzuahmen, wäre, eine boolesche Variable vom Typ __block zu erstellen und sie am Anfang des Blocks zu überprüfen. Wenn es eingestellt ist, schnell aussteigen. Sie müssten den Block immer noch durch die restlichen Iterationen laufen lassen, aber es wäre schneller.

    
BJ Homer 23.06.2010 21:16
quelle
1

Sie können nicht break a dispatch_apply , da es unlogisch ist.

In -enumerateObjectsUsingBlock: ist eine Pause wohldefiniert, weil die Funktionen sequentiell ausgeführt werden. In dispatch_apply werden die Funktionen jedoch parallel ausgeführt. Das heißt, beim Aufruf des Blocks " i=3 rd" hätte der i=4 th-Aufruf gestartet werden können. Wenn Sie break at i=3 verwenden, sollte der Aufruf i=4 noch ausgeführt werden?

@BJ ist die Antwort am nächsten können Sie tun, aber es wird immer einige "Spill-over".

    
kennytm 23.06.2010 21:22
quelle