2013-04-07 2 views
7

Ich möchte eine Methode für meine Klasse wie enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) aus der NSDictionary Klasse machen.Wie verwendet man eine Stoppbedingung für einen Block wie den enumerateObjectsUsingBlock aus der NSDictionary-Klasse?

Ich habe ein wenig Wissen über die Verwendung von Blöcken, aber ich war nicht in der Lage, herauszufinden, wie die Stop-Bedingung, die die enumerateObjectsUsingBlock-Funktion verwendet. Irgendwelche Vorschläge?

Antwort

13

Die stop Flag wird wie folgt verwendet:

[coll enumerateUsingBlock:^(id o, NSUInteger i, BOOL *stop) { 
     if (... check for stop ...) { 
      *stop = YES; 
      return; 
     } 
}]; 

Wenn die Aufzählung Block zurückgibt, die Sammlung überprüft *stop. Wenn es YES ist, hört es auf zu zählen.

Es wird auf diese Weise implementiert, im Gegensatz zu einem Rückgabewert, da dies eine gleichzeitige Aufzählung ermöglicht, ohne den Rückgabewert des Blocks zu überprüfen (was einen Overhead verursachen würde). I.e. Bei gleichzeitiger Aufzählung kann die Sammlung dispatch_async() beliebig viele gleichzeitige Iterationen und regelmäßig überprüfen *stop. Immer wenn *stop zu YES übergeht, hört es auf, weitere Blöcke zu planen (das ist auch der Grund, warum das Flag stop kein Hardstop ist; einige nicht spezifizierte Anzahl von Iterationen befindet sich möglicherweise noch im Flug).

In Ihrem Iterator, könnten Sie tun:

BOOL stop = NO; 
for(...) { 
    enumerationBlock(someObj, someIndex, &stop); 
    if (stop) break; 
} 
+0

Dank, das funktioniert perfekt. Die Lösung zu dieser Frage finden Sie auch hier: http://www.informit.com/blogs/blog.aspx?uk=Ask-Big-Nerd-Ranch-Blocks-in-Objective-C –

6

Der folgende Code definiert eine Methode, die einen Block als Parameter übernimmt und hält es die Ausführung bis shouldStop zu NO durch den Block festgelegt ist.

- (void)myMethod:(void(^)(BOOL *stop))aBlock { 
    BOOL shouldStop = NO; 
    while (!shouldStop) { 
     aBlock(&shouldStop); 
    } 
} 

Die Erklärung ist ziemlich einfach. Ein Block ist eine Funktion, die einige Parameter benötigt. In diesem Fall übergeben wir als Parameter einen Zeiger auf eine BOOL Variable, die wir besitzen. Indem wir dies tun, erlauben wir dem Block, diese Variable zu setzen und - in diesem Fall - anzuzeigen, dass die Schleife stoppen sollte.

An diesem Punkt wird der Block etwas tun geben könnte wie

[self myMethod:^(BOOL *stop) { 
     if (arc4random_uniform(1)) { 
      *stop = YES; 
     } 
}]; 
Verwandte Themen