Search code examples
objective-cios5ios6objective-c-blocks

Variables for controlling array iteration on iOS 5


I have seen somewhere that the following three codes are doing the same thing.

Using loops:

BOOL stop = 0;
for (int i = 0 ; i < [theArray count] ; i++) {
    NSLog(@"The object at index %d is %@",i,[theArray objectAtIndex:i]);
    if (stop)
        break;
}

Using fast enumeration:

int idx = 0;
BOOL stop = 1;

for (id obj in theArray) {
    NSLog(@"fast emuration approch @ x %d is %@",idx,obj);
    if (stop)
        break;
    idx++;
}

Using blocks:

[theArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop){

    NSLog(@"the block approch at x %d is %@",idx,obj);
}];

But what I don't understand is -

  1. How can I set stop from outside in the block approach?
  2. How can I set idx in the block approach?
  3. BOOL declaration is unusual in block approach .why? (Because I am not able to change the value within the block also , is it because of such declaration?)

Solution

    1. You can only change the value pointed to by stop within the block - but as far as semantics are concerned, you can't do any different in the other approaches, either, unless you're using a variable with broader scope that indicated by your sample code and manipulating it on another thread.
    2. You can't. The code you write in the block is your loop body, essentially, and idx and stop are passed from the calling context of the block, where they serve to control the iteration within that context. I mean, within the implementation of the enumerateObjectsUsingBlock: method, it sets up locals idx and stop as you do in the fast enumeration method, and passes them as arguments to the block.
    3. You receive a pointer to a BOOL you can change the value that the caller sees. That is, from within the block you set *stop to YES and the implementation of enumerateObjectsUsingBlock: will see that its local variable stop has been set to YES. This is the typical way of returning multiple arguments by reference in C.