web-dev-qa-db-fra.com

Objective-C NSMutableArray - boucle foreach avec des objets de plusieurs classes

J'ai les enfants NSMutableArray * dans la classe de structure de données "Foo" qui est la superclasse de beaucoup d'autres, comme "Bar1" et "Bar2". Ce tableau stocke les objets Bar1 et Bar2 pour obtenir une structure parent-enfant récursive arborescente de sous-classes de Foo. Pour accéder aux objets du tableau, je les parcourt en utilisant la boucle foreach dans Objective-C:

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

Mais souvent, je n'ai besoin que de parcourir les objets du tableau qui ont une certaine classe, dans ce cas, je veux effectuer une tâche pour chaque objet de la classe Bar1 dans les enfants du tableau. L'utilisation de (Bar1 * anObject chez les enfants) fait à nouveau une boucle sur TOUS les objets et pas seulement ceux avec la classe Bar1. Existe-t-il un moyen de réaliser ce dont j'ai besoin?

20
Nils Fischer

Vous devez faire une boucle sur tous les objets et faire une vérification de type à l'intérieur de la boucle.

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

Vous pouvez faire quelque chose comme ça:

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

Il est important de noter, cependant, que cela ne fonctionnera pas avec de nombreuses classes Cocoa standard comme NSString, NSNumber, etc. qui utilisent des clusters de classes ou des classes d'implémentation spéciales (par exemple, tout ce qui est sans frais ponté avec un type CoreFoundation) depuis le les classes ne correspondront pas exactement. Cependant, cela fonctionnera avec les classes que vous définissez tant que la classe est vraiment une instance de Bar1.

Note d'accentuation: L'utilisateur @Alex a suggéré qu'il peut ne pas être clair que les classes doivent correspondre exactement à ma note ci-dessus, donc je répète cela. Les classes doivent correspondre exactement pour que ce filtre fonctionne, donc si vous sous-classe Bar1 ou fournissez une classe proxy, vous devrez ajuster le filtre pour que ces classes soient incluses. Tel qu'écrit, uniquement les instances de Bar1 sera retourné dans le tableau filtré.

12
Jason Coco