SIGPIPE 13

Iterating an Array

September 13th, 2004

Over at CocoaDev they are discussing how to efficiently iterate an NSArray.

I would really never ever think that the way you iterate an NSArray has any impact on the perceived performance of your program (granted you do not change the time complexity or do other stupid things), I would however think that it affects the perceived complexity of the source.

Here is the "ideal" iteration using an NSEnumerator.

NSEnumerator* enumerator = [array objectEnumerator];
while(id obj = [enumerator nextObject])
   NSLog("%@", obj);

Even with the help of TextMate's placeholder savvy snippets, I really do not want that inserted each time I must run through all the elements of an array, so I created this macro:

#ifndef forall
#define forall(container,var) \
   for(id _enumerator = [container objectEnumerator], var; \
       var = [_enumerator nextObject]; )
#endif

It can be used like this:

forall(array, obj)
   NSLog("%@", obj);

And you may even change it to using objectAtIndex: or perhaps even CFArray functions, and you'll see the benefits throughout your program :)

[by Allan Odgaard]


7 Responses to “Iterating an Array”

  1. wzph Says:
    September 15th, 2004 at 05:14

    I like that. I'll have to try it out. After a long time of avoiding them, I am beginning to embrace macros. Good thinking!

  2. Scott Stevenson Says:
    September 16th, 2004 at 00:41

    What about -makeObjectsPerformSelector:?

  3. Allan Odgaard Says:
    September 16th, 2004 at 00:45

    You mean instead of doing manual iteration? This is great if all you need to do is send a message to all the objects in the array, but that unfortunately does not cover all cases.

  4. Scott Stevenson Says:
    September 16th, 2004 at 01:01

    Well, the selector could likely implement whatever you need to do in the block.

    I realize this might be a difference of opinion, but I don't favor using macros just because they work in the siutation. I usually save them as a last resort type of thing. My experience is that they make code harder to follow, ala goto.

  5. Allan Odgaard Says:
    September 16th, 2004 at 01:22

    I'm not sure I really follow you. Putting the loop body in a selector can't always solve the problem, e.g. you can only pass it one argument, you cannot terminate the loop prematurely, you need either an array containing homogenous objects and/or objects you have the source for, unless you want to start writing NSObject categories for your loop bodies, and you remove the actual code from the loop.

    Had ObjectiveC supported anonymous functions, closures, blocks, or whatever, then I would probably also favor such a solution in many cases — but it currently does not.

    With regard to macros, well, yes, they are a last resort, and I have less than 10 macros in my programming tool suite (stuff like debug output and assertions really cannot be done w/o macros, if you want an easy way to not have that code en deployment builds).

    And in this particular case, I doubt you can argue that a forall() makes the code harder to follow. Most languages even have such a construct to support the frameworks iteration scheme.

  6. Scott Stevenson Says:
    September 16th, 2004 at 10:24

    I guess the thing that struck me was wzph's comment. I visualized him running out and making a bunch of macros now. :) I'd present it as "if you find yourself stuck, don't forget about macros." I've seen too much source code that uses the preprocessor far too liberally.

    And to get technical about it, passing one argument is never really a problem because you can always provide a dictionary. Fair point about jumping out of the loop, though. I would, however, say that the vast majority of arrays probably have only one type of object in them.

  7. wzph Says:
    September 24th, 2004 at 23:58

    Somebody help me! I can't stop making macros! Just kidding. I didn't give much background to my initial post, but what I should have written was "I have always loathed–even been afraid of–macros, and I am just beginning to see them for what they are: a helpful tool in the right situation. It was serendipitous to stumble upon this post when I did."


Leave a Reply