How does Fast Enumeration (looping) work in Objective-C? (i.e. for (NSString * aString in aDictionary) ...)

I am working on implementing a custom searchBar for a rather complex table and have come across this AGAIN code. This is a sample from an iPhone starter development book:

- (void)handleSearchForTerm:(NSString *)searchTerm { NSMutableArray *sectionsToRemove = [[NSMutableArray alloc] init]; [self resetSearch]; for (NSString *key in self.keys) { NSMutableArray *array = [self.names valueForKey:key]; NSMutableArray *toRemove = [[NSMutableArray alloc] init]; for (NSString *name in array) { if ([name rangeOfString:searchTerm options:NSCaseInsensitiveSearch].location == NSNotFound) [toRemove addObject:name]; } if ([array count] == [toRemove count]) [sectionsToRemove addObject:key]; [array removeObjectsInArray:toRemove]; [toRemove release]; } [self.keys removeObjectsInArray:sectionsToRemove]; [sectionsToRemove release]; [table reloadData]; } 

The parts that interest me are the "for (NSString * name in array)" section. What does it do? It seems a row is being created for each element of the array. Also, how does this work with dictionaries?

Thanks!

+6
dictionary arrays loops iphone
source share
3 answers

This construction is a different type of for loop that processes elements in the Objective-C collection, and not in array C. The first part defines the object that is installed into one element in the collection, each run of the cycle, and the second part is a list to be enumerated . For example, the code:

 NSArray *array = [NSArray arrayWithObjects:@"foo", @"bar", nil]; for(NSString *string in array) { NSLog(string); } 

will print:

  foo
 bar 

By defining an NSString *string , each loop in the loop gets the next object in the NSArray *array .

Similarly, you can use the enumeration with instances of NSSet (where the order of the objects is not defined) and NSDictionary (where it will enumerate the keys stored in the dictionary), you can list the values โ€‹โ€‹by listing by keys, then calling valueForKey: in the dictionary using this key) .

This is very similar to the construct in C:

 int array[2] = { 0, 1 }; for(int i = 0; i < 2; i++) { printf("%d\n", array[i]); } 

which prints:

  0
 one 

This is just a syntactic way to make the code more readable and hide some of the fancy enumerations that go into enumeration objects in NSArray, NSSet, or NSDictionary. For more information, see the Fast Enumeration section of the Objective-C 2.0 programming language document.

+15
source share

This is called a quick listing. It moves through the array, setting a key for each element. This is the same, functionally, as it does:

 NSString *key; for ( NSInteger i = 0; i < [[ self keys ] count ]; i++ ) { key = [[ self keys ] objectAtIndex:i ]; NSMutableArray *array = [self.names valueForKey:key]; NSMutableArray *toRemove = [[NSMutableArray alloc] init]; for (NSString *name in array) { if ([name rangeOfString:searchTerm options:NSCaseInsensitiveSearch].location == NSNotFound) [toRemove addObject:name]; } if ([array count] == [toRemove count]) [sectionsToRemove addObject:key]; [array removeObjectsInArray:toRemove]; [toRemove release]; } 
+3
source share

This is a for loop with one iteration for each key in the dictionary.

The for..in construct is called a quick enumeration. You can read more about this in the Objective-C 2.0 Programming Guide .

How this works with an object depends on its implementation of the NSFastEnumeration protocol. The link link to NSDictionary describes how it works with dictionaries:

On Mac OS X version 10.5 and later, NSDictionary supports the NSFastEnumeration protocol. You can use the for ... in construct to enumerate dictionary keys, as shown in the following example.

+2
source share

All Articles