Действительно ли возможно отфильтровать NSArray классом?

Существует ли дорожная конструкция предикат для фильтрации типом класса?

Я в настоящее время цикл через массив и проверку к классу каждого объекта. Возможно, существует более чистый путь?

24
задан Corey Floyd 31 March 2010 в 16:57
поделиться

2 ответа

Вы можете добавить категорию в NSObject, которая добавляет метод cf_className, например Итак:

@interface NSObject (CFAdditions)
- (NSString *) cf_className;
@end

@implementation NSObject (CFAdditions)
- (NSString *) cf_className {
  return NSStringFromClass([self class]);
}
@end

Оттуда вы можете использовать такие предикаты, как:

NSPredicate * p = [NSPredicate predicateWithFormat:@"cf_className = %@", aClass];
NSArray * filtered = [anArray filteredArrayUsingPredicate:p];

Если вы работаете на Mac, вы можете просто использовать - [NSObject className] вместо того, чтобы создавать категорию. В iPhone такого метода нет, отсюда и необходимость в категории.

22
ответ дан 28 November 2019 в 22:07
поделиться

Вы также можете напрямую сравнивать классы в своем предикате.

Но, вероятно, это не сработает так, как вы ожидаете, если вы пытаетесь фильтровать объекты, принадлежащие кластерам классов, или если у вас есть подклассы.

Например, NSDate при создании экземпляра обычно является __ NSCFDate , а NSString может быть NSCFString , а также другими частными классами.

Вероятно, лучше просто прокрутить набор самостоятельно и использовать -isKindOfClass: в качестве теста.

ЕСЛИ вы действительно хотите использовать NSPredicate , хотя вы можете это сделать. Например, это отфильтрует массив для всех объектов, производных от NSString . Если вам нужно строгое членство в классе, вы можете заменить isKindOfClass: на isMemberOfClass: .

Любой селектор, который реализует все объекты в коллекции, принимает один аргумент и возвращает BOOL , тем не менее, должен работать.

NSArray *mixedArray = {...};
NSPredicate *predicate = [NSPredicate predicateWithFormat:
                                      @"self isKindOfClass: %@",
                                      [NSString class]];

NSLog(@"%@", [mixedArray filteredArrayUsingPredicate:predicate]);
76
ответ дан 28 November 2019 в 22:07
поделиться