Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use a stop condition on a block like the enumerateObjectsUsingBlock from the NSDictionary class?

I want to make a method on my class like enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) from the NSDictionary class.

I have a little knowledge on blocks usage, but I have not been able to figure out how to make the stop condition that the enumerateObjectsUsingBlock function uses. Any suggestions?

like image 607
Alejandro Cotilla Avatar asked Apr 07 '13 22:04

Alejandro Cotilla


1 Answers

The stop flag is used like this:

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

When the enumeration block returns, the collection checks *stop. If it is YES, it stops enumerating.

It is implemented this way, as opposed to a return value, because this allows for concurrent enumeration without checking the return value of the block (which would incur overhead). I.e. in concurrent enumeration, the collection can dispatch_async() any number of simultaneous iterations and periodically check *stop. Whenever *stop transitions to YES, it stops scheduling more blocks (this is also why the stop flag is not a hard stop; some unspecified number of iterations may still be in flight).

In your iterator, you might do:

 BOOL stop = NO;
 for(...) {
     enumerationBlock(someObj, someIndex, &stop);
     if (stop) break;
 }
like image 175
bbum Avatar answered Sep 19 '22 10:09

bbum