Question

I apologize if this question is exceedingly simple, but I've Googled like crazy and am unable to find a suitable explanation for what this is.

for (id line in self.lines){
    [linesCopy addObject:[line copyWithZone:zone]];
}

I'm just learning Objective-C, and this is a form of for loop that I've never seen before. I'm familiar with the simple

for (int x = 1, x < 10, x++)

style of for loop.

Was it helpful?

Solution

From Cocoa Core Competencies: Enumeration:

Fast Enumeration

Several Cocoa classes, including the collection classes, adopt the NSFastEnumeration protocol. You use it to retrieve elements held by an instance using a syntax similar to that of a standard C for loop, as illustrated in the following example:

NSArray *anArray = // get an array;
for (id element in anArray) {
    /* code that acts on the element */
}

As the name suggests, fast enumeration is more efficient than other forms of enumeration.

In case you didn't know, id is an Objective-C type that basically means “a pointer to any Objective-C object”. Note that the pointer-ness of id is built in to it; you usually do not want to say id *.

If you expect the elements of anArray to be of a specific class, say MyObject, you can use that instead:

for (MyObject *element in anArray) {
    /* code that acts on the element */
}

However, neither the compiler nor the runtime will check that the elements are indeed instances of MyObject. If an element of anArray is not an instance of MyObject, you'll probably end up trying to send it a message it doesn't understand, and get a selector-not-recognized exception.

OTHER TIPS

It's the shorthand equivalent of this common form:

for (int i = 0; i < [self.lines count]; i++) {
    id line = [self.lines objectAtIndex:i];
    // ...
}

It's such a common looping idiom (walking through some collection, array, set, etc. an item at a time), that it's been turned into a shorthand form like this, called "fast enumeration".

In fact, in its internal implementation, it's actually slightly more faster than doing it yourself, so it's preferable both for clarity and performance.

It's a statement that can be used with classes that are conform to NSFastEnumeration protocol. When you have this available, the Objective-C programming guide suggest you to use it. Take a look here. It's a way to iterate over a collection without the traditional for (int i = 0; i < length; ++i) syntax.

Mind that it doesn't usually support deleting and inserting elements while iterating through this way (also by using normal for loops you should take care about indices in any case).

Basically all standard collections supports this way of iteration.

It's called a forin loop, also called fast enumeration. Basically, the syntax is:

for (SomeObjectIAmExpecting *localVariableName in anArrayOfObjects)
{
    if (![localVariableName isKindOfClass:[SomeObjectIAmExpecting class]]) continue; //To avoid errors.
     //do something to them
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top