Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple NSArray enumeration

Let's say I have three arrays of same size. I have to do something with all objects. If I would use a standard C array, I would write something like

for (i = 0; i < size; i++) {
    doSomething(array1[i]);   // or [[array1 objectAtIndex:i] doSomething];
    doSomethingElse(array2[i]);   // or [[array2 objectAtIndex:i] doSomethingElse];
    doSomethingReallySpecial(array3[i]);   // or [[array3 objectAtIndex:i] doSomethingReallySpecial];
}

With Objective C we got more ways to cycle through objects in NSArray: fast enumeration, block-based enumeration and using enumerators. Which one should I use and why? What's the difference?

Edit
Actually this question may be formulated like this: if one needs to use the index of an item of an array, which enumeration should be used?

like image 780
adubr Avatar asked Oct 12 '22 01:10

adubr


1 Answers

NSEnumerator-based methods were once the only supported way to enumerate. I can't think of any advantages it has over the others - it's slower and more unwieldy and has largely been superseded by the other methods.

Using blocks allows a lot flexibility. A method could accept a block as argument and use that to enumerate over several different collections:

- (void) doSomethingToFruits:(void(^)(id,NSUInteger,BOOL*))block
{
    [apples enumerateObjectsUsingBlock:block];
    [bananas enumerateObjectsUsingBlock:block];
    [kiwis enumerateObjectsUsingBlock:block];
}

You can also use the options argument in enumerateObjectsUsingBlock:options: to enumerate over contents concurrently,.

Something I like about fast enumeration is that the NSFastEnumeration protocol allows me to add a method that accepts either arrays or sets, (or hashtables or whatever) but still has static type checking on the argument:

- (void) addObjectsFromCollection:(id<NSFastEnumeration>)coll
{
    for (id obj in coll) [self addObject:obj];
}

Otherwise, the syntax of the two just seem to fit better in different contexts. I find that if the main body of a method is enumerating over a collection it's clearer what is going on if I use fast enumeration, whereas if I just want to perform one or two actions on all contents in the middle of a larger method, blocks are more concise, but I guess this part is down to personal preference.

Addendum:

If you want to keep track of the index, the block option accepts an index as argument.

like image 173
Chris Devereux Avatar answered Oct 14 '22 05:10

Chris Devereux