2010-06-14 30 views
18

Ich habe die NSMutableArray * Kinder in der Datenstruktur-Klasse "Foo", die die Oberklasse von vielen anderen ist, wie "Bar1" und "Bar2". Dieses Array speichert Bar1- und Bar2-Objekte, um eine baumartige rekursive Eltern-Kind-Struktur von Unterklassen von Foo zu erhalten. Um die Objekte in dem Array zuzugreifen, ich Schleife durch sie die foreach-Schleife in Objective-C mit:Objective-C NSMutableArray - foreach Schleife mit Objekten aus mehreren Klassen

for(Foo *aFoo in children) { 
    ... 
} 

Aber oft in der Anordnung durch die Objekte in einer Schleife, die eine bestimmte Klasse, ich brauche nur in diesem Fall Ich möchte eine Aufgabe für jedes Objekt der Klasse Bar1 in den Array-Children ausführen. Die Verwendung von for (Bar1 * anObject in Kindern) durchläuft wiederum ALLE Objekte und nicht nur diejenigen mit der Klasse Bar1. Gibt es eine Möglichkeit, das zu erreichen, was ich brauche?

Antwort

40

Sie müssen alle Objekte durchlaufen und eine Typprüfung in der Schleife durchführen.

for(id aFoo in children) { 
    if ([aFoo isKindOfClass:[Bar1 class]]) 
     ... 
    } 
} 
+1

das kann ziemlich speicher teuer sein, aber anscheinend gibt es keinen anderen Weg. Danke –

+5

nein, es ändert nicht Ihren Speicherabdruck, Sie lesen gerade, was bereits im Gedächtnis ist – unbeli

+3

Im Allgemeinen, wenn Sie 'isKindOfClass:' verwenden müssen, um zwischen Klassen in einer Ansammlung zu unterscheiden, ist Ihr Entwurfsmuster außerhalb der Norm. Dies gilt insbesondere dann, wenn Ihre Sammlung Instanzen von Klassen enthält, die vollständig von Ihnen erstellt wurden. – bbum

9

Sie können so etwas tun:

NSPredicate* bar1Predicate = [NSPredicate predicateWithFormat:@"SELF.class == %@", [Bar1 class]]; 
NSArray* bar1z = [children filteredArrayUsingPredicate:bar1Predicate]; 
for(Bar1* bar in children) { 
    // do something great 
} 

Es ist wichtig zu beachten Sie jedoch, dass dies nicht mit vielen Standard-Cocoa-Klassen wie NSString arbeiten, NSNumber usw., die Klasse Cluster verwenden oder spezielle Implementierungsklassen (z. B. alles, was gebührenfrei mit einem CoreFoundation-Typ überbrückt wird), da die Klassen nicht genau übereinstimmen. Dies funktioniert jedoch mit Klassen, die Sie definieren, solange die Klasse eine Instanz von Bar1 ist.

Hervorhebungsnotiz: Benutzer @Alex schlug vor, dass es nicht klar sein kann, dass die Klassen genau von meiner Anmerkung oben übereinstimmen müssen, also wiederhole ich das. Die Klassen müssen genau übereinstimmen, damit dieser Filter funktioniert. Wenn Sie also Bar1 ableiten oder eine Proxy-Klasse bereitstellen, müssen Sie den Filter anpassen, damit diese Klassen eingeschlossen werden. Wie beschrieben, werden nur Instanzen von Bar1 im gefilterten Array zurückgegeben.

+0

auch, ich denke, das ist nicht auf dem iPhone verfügbar – unbeli

+2

@unbeli: Es ist absolut auf dem iPhone verfügbar, nicht, dass das OP das iPhone überhaupt erwähnt. –

+0

Aber, wenn Sie jemals Bar1 ableiten, wird dieser Code nicht mit Objekten der Unterklasse übereinstimmen. Das OP sagt nichts über Unterklassen aus, aber es ist wichtig zu beachten. – Alex

Verwandte Themen