Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the BOOL *stop argument for enumerateObjectsUsingBlock: used for?

I've been using enumerateObjectsUsingBlock: a lot lately for my fast-enumeration needs, and I'm having a hard time understanding the usage of BOOL *stop in the enumeration block.

The NSArray class reference states

stop: A reference to a Boolean value. The block can set the value to YES to stop further processing of the array. The stop argument is an out-only argument. You should only ever set this Boolean to YES within the Block.

So then of course I can add the following in my block to stop the enumeration:

if (idx == [myArray indexOfObject:[myArray lastObject]]) {     *stop = YES; } 

From what I've been able to tell, not explicitly setting *stop to YES doesn't have any negative side effects. The enumeration seems to automatically stop itself at the end of the array. So is using *stop really necessary in a block?

like image 581
Mick MacCallum Avatar asked Sep 10 '12 19:09

Mick MacCallum


1 Answers

The stop argument to the Block allows you to stop the enumeration prematurely. It's the equivalent of break from a normal for loop. You can ignore it if you want to go through every object in the array.

for( id obj in arr ){     if( [obj isContagious] ){         break;    // Stop enumerating     }      if( ![obj isKindOfClass:[Perefrigia class]] ){         continue;    // Skip this object     }      [obj immanetizeTheEschaton]; } 

[arr enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {     if( [obj isContagious] ){         *stop = YES;    // Stop enumerating         return;     }      if( ![obj isKindOfClass:[Perefrigia class]] ){         return;    // Skip this object     }      [obj immanentizeTheEschaton]; }]; 

That is an out parameter because it is a reference to a variable from the calling scope. It needs to be set inside your Block, but read inside of enumerateObjectsUsingBlock:, the same way NSErrors are commonly passed back to your code from framework calls.

- (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block {     // N.B: This is probably not how this method is actually implemented!     // It is just to demonstrate how the out parameter operates!      NSUInteger idx = 0;     for( id obj in self ){          BOOL stop = NO;          block(obj, idx++, &stop);          if( stop ){             break;         }     } } 
like image 180
jscs Avatar answered Sep 22 '22 20:09

jscs