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 Syntax

The syntax for fast enumeration 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:

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

In other respects, the feature behaves like a standard for loop. You can use break to interrupt the iteration and continue to advance to the next element.

Adopting Fast Enumeration

Any class whose instances provide access to a collection of other objects can adopt the NSFastEnumeration protocol. The collection classes in the Foundation framework—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 this 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 an NSArray or an NSEnumerator instance derived from an array—the enumeration proceeds in that order, so simply counting iterations gives you the proper index into the collection if you need it.

NSArray *array = <#Get an array#>;
NSUInteger index = 0;
 
for (id element in array) {
    NSLog(@"Element at index %u is: %@", index, element);
    index++;
}