Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective-C NSMutableArray - foreach loop with objects of multiple classes

I have the NSMutableArray *children in the datastructure-class "Foo" which is the superclass of many others, like "Bar1" and "Bar2". That array stores Bar1 and Bar2 objects to get a tree-like recursive parent-children-structure of subclasses from Foo. To access the objects in the array, I loop through them using the foreach loop in Objective-C:

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

But often I only need to loop through the objects in the array that have a certain class, in this case I want to perform a task for each object of the class Bar1 in the array children. Using for(Bar1 *anObject in children) again loops through ALL objects and not only the ones with the class Bar1. Is there a way to achieve what I need?

like image 397
Nils Fischer Avatar asked Jun 14 '10 13:06

Nils Fischer


2 Answers

You have to loop over all objects and do a type check inside the loop.

for(id aFoo in children) {
    if ([aFoo isKindOfClass:[Bar1 class]])
        ...
    }
}
like image 149
unbeli Avatar answered Oct 23 '22 11:10

unbeli


You can do something like this:

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

It's important to note, however, that this won't work with many standard Cocoa classes like NSString, NSNumber, etc. that use class clusters or special implementation classes (e.g., anything that is toll-free bridged with a CoreFoundation type) since the classes won't match exactly. However, this will work with classes you define as long as the class really is an instance of Bar1.

Emphasis Note: User @Alex suggested that it may not be clear that the classes must match exactly from my note above, so I am restating that. The classes must match exactly for this filter to work, so if you subclass Bar1 or provide some proxy class, you will have to adjust the filter in order for those classes to be included. As written, only instances of Bar1 will be returned in the filtered array.

like image 14
Jason Coco Avatar answered Oct 23 '22 11:10

Jason Coco