2009-08-21 1 views
6

Ich arbeite an der Implementierung einer angepassten searchBar für eine ziemlich komplexe Tabelle und bin auf dieses Codemuster AGAIN gestoßen. Dies ist ein Beispiel von Anfang iPhone Entwicklung Buch:Wie funktioniert Fast Enumeration (Schleifen) in Objective-C? (zB: for (NSString * aString in aDictionary) ...)

- (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]; 
} 

Der Teil I gespannt bin, ist der „für (NSString * Name in Array)“ Abschnitt. Was macht das genau? Es scheint eine Zeichenfolge für jedes Element im Array zu erstellen. Wie funktioniert das mit Wörterbüchern?

Danke!

+0

Vielen Dank für die schnelle Antwort jeder! Ich habe den Titel so bearbeitet, dass er "schnelle Aufzählung" enthält. – Jonah

Antwort

15

Dieses Konstrukt ist eine andere Art von for Schleife, die über Elemente in einer Objective-C-Auflistung anstelle von C-Array ausgeführt wird. Der erste Teil definiert ein Objekt, das bei jedem Durchlauf der Schleife auf ein Element in der Sammlung gesetzt wird, während der zweite Teil die aufzuzählende Sammlung ist. Zum Beispiel kann der Code:

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

würde drucken:

foo 
bar

Es ist ein NSString *string definiert, die, jeder Lauf der Schleife, auf das nächste Objekt in den NSArray *array gesetzt wird.

In ähnlicher Weise können Sie die Enumeration mit NSSet-Instanzen (wobei die Reihenfolge der Objekte nicht definiert ist) und NSDictionary (wo sie die im Dictionary aufgelisteten Schlüssel aufzählen) verwenden. Sie können die Werte durch Aufzählung über Schlüssel aufzählen. dann rufen Sie valueForKey: auf dem Wörterbuch mit diesem Schlüssel).

Es ist extrem ähnlich das Konstrukt in C:

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

die druckt:

0 
1

Es ist nur eine syntaktische Art und Weise des Code besser lesbar zu machen und einige der Phantasie Aufzählung versteckt, die geht um Objekte in einem NSArray, NSSet oder NSDictionary aufzulisten. Weitere Einzelheiten finden Sie im Abschnitt Fast Enumeration des Dokuments Objective-C 2.0 Programmiersprache.

2

Es ist eine for-Schleife mit einer Iteration für jeden Schlüssel im Wörterbuch.

Das for..in Konstrukt heißt Fast enumeration. Sie können mehr darüber in Objective-C 2.0 Programming Guide lesen.

Wie es mit einem Objekt funktioniert, hängt von der Implementierung des NSFastEnumeration-Protokolls ab. Die NSDictionary class reference beschreibt, wie es mit Wörterbüchern arbeitet:

Unter Mac OS X 10.5 und höher, NSDictionary unterstützt das NSFastEnumeration Protokoll. Sie können das Konstrukt for ... in verwenden, um die Schlüssel eines Dictionary aufzuzählen, wie im folgenden Beispiel gezeigt.

3

Dies wird schnelle Aufzählung genannt. Es durchläuft das Array und setzt key auf jedes Element.Es ist das gleiche, funktionell, wie dies tun:

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]; 
}