Mac OS X Reference Library Apple Developer
Search

Fast Enumeration

Fast enumeration is a language feature that allows you to efficiently and safely enumerate over the contents of a collection using a concise syntax.

The for…in Feature

Fast enumeration is a language feature that allows you to enumerate over the contents of a collection. The syntax is defined as follows:

for ( Type newVariable in expression ) { statements }

or

Type existingItem;
for ( existingItem in expression ) { statements }

In both cases, expression yields an object that conforms to the NSFastEnumeration protocol (see “Adopting Fast Enumeration”). The iterating variable is set to each item in the returned object in turn, and the code defined by statements is executed. The iterating variable is set to nil when the loop ends by exhausting the source pool of objects. If the loop is terminated early, the iterating variable is left pointing to the last iteration item.

There are several advantages to using fast enumeration:

Since mutation of the object during iteration is forbidden, you can perform multiple enumerations concurrently.

Adopting Fast Enumeration

Any class whose instances provide access to a collection of other objects can adopt the NSFastEnumeration protocol. The Cocoa collection classes—NSArray, NSDictionary, and NSSet—adopt this protocol, as does NSEnumerator. It should be obvious that in the cases of NSArray and NSSet the enumeration is over their contents. For other classes, the corresponding documentation should make clear what property is iterated over—for example, NSDictionary and the Core Data class NSManagedObjectModel provide support for fast enumeration; NSDictionary enumerates its keys, and NSManagedObjectModel enumerates its entities.

Using Fast Enumeration

The following code example illustrates using fast enumeration with NSArray and NSDictionary objects.

NSArray *array = [NSArray arrayWithObjects:
        @"One", @"Two", @"Three", @"Four", nil];
 
for (NSString *element in array) {
    NSLog(@"element: %@", element);
}
 
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
    @"quattuor", @"four", @"quinque", @"five", @"sex", @"six", nil];
 
NSString *key;
for (key in dictionary) {
    NSLog(@"English: %@, Latin: %@", key, [dictionary objectForKey:key]);
}

You can also use NSEnumerator objects with fast enumeration, as illustrated in the following example:

NSArray *array = [NSArray arrayWithObjects:
        @"One", @"Two", @"Three", @"Four", nil];
 
NSEnumerator *enumerator = [array reverseObjectEnumerator];
for (NSString *element in enumerator) {
    if ([element isEqualToString:@"Three"]) {
        break;
    }
}
 
NSString *next = [enumerator nextObject];
// next = "Two"

For collections or enumerators that have a well-defined order—such as NSArray or NSEnumerator instance derived from an array—the enumeration proceeds in that order, so simply counting iterations will give you the proper index into the collection if you need it.

NSArray *array = /* assume this exists */;
NSUInteger index = 0;
 
for (id element in array) {
    NSLog(@"Element at index %u is: %@", index, element);
    index++;
}

In other respects, the feature behaves like a standard for loop. You can use break to interrupt the iteration; and if you want to skip elements you can use a nested conditional statement as shown in the following example:

NSArray *array = /* assume this exists */;
 
for (id element in array) {
    if (/* some test for element */) {
        // statements that apply only to elements passing test
    }
}

If you want to skip the first element then process no more than five further elements, you could do so as shown in this example:

NSArray *array = /* assume this exists */;
NSUInteger index = 0;
 
for (id element in array) {
     if (index != 0) {
          NSLog(@"Element at index %u is: %@", index, element);
     }
 
     if (++index >= 6) {
          break;
     }
}



Last updated: 2010-07-13

Did this document help you? Yes It's good, but... Not helpful...