Objective-C NSMutableArray - цикл foreach с объектами нескольких классов - PullRequest
19 голосов
/ 14 июня 2010

У меня есть дети NSMutableArray * в классе структуры данных "Foo", который является суперклассом многих других, таких как "Bar1" и "Bar2".Этот массив хранит объекты Bar1 и Bar2, чтобы получить древовидную рекурсивную структуру parent-children подклассов от Foo.Чтобы получить доступ к объектам в массиве, я перебираю их с помощью цикла foreach в Objective-C:

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

Но часто мне нужно только перебирать объекты в массиве, которые имеют определенный классВ этом случае я хочу выполнить задачу для каждого объекта класса Bar1 в массиве потомков.Использование for (Bar1 * anObject в дочерних элементах) снова перебирает ВСЕ объекты, а не только объекты с классом Bar1.Есть ли способ добиться того, что мне нужно?

Ответы [ 2 ]

40 голосов
/ 14 июня 2010

Вы должны перебрать все объекты и выполнить проверку типа внутри цикла.

for(id aFoo in children) {
    if ([aFoo isKindOfClass:[Bar1 class]])
        ...
    }
}
11 голосов
/ 14 июня 2010

Вы можете сделать что-то вроде этого:

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

Важно отметить, однако, что это не будет работать со многими стандартными классами Какао, такими как NSString, NSNumber и т. Д., Которые используют кластеры классов или специальныеклассы реализации (например, все, что бесплатно для мостов с типом CoreFoundation), так как классы не будут точно совпадать.Тем не менее, это будет работать с классами, которые вы определяете, пока класс действительно является экземпляром Bar1.

Примечание об акценте : пользователь @Alex предположил, что, возможно, не ясно, что классы должныточно соответствует моей записке выше, поэтому я повторяю это.Классы должны точно соответствовать, чтобы этот фильтр работал, поэтому, если вы создаете подкласс Bar1 или предоставляете какой-то прокси-класс, вам нужно будет настроить фильтр для включения этих классов.Как написано, только экземпляров Bar1 будут возвращены в отфильтрованном массиве.

...