有没有办法构造一个谓词来按类类型过滤?
我目前循环遍历数组并检查每个对象的类。也许有一种更清洁的方式?
答案 0 :(得分:74)
您也可以在谓词中直接比较类。
但是,如果您尝试过滤属于类集群的对象或者您有子类,它可能无法正常工作。
例如,实例化时NSDate
通常为__NSCFDate
,NSString
可以是NSCFString
以及其他特定私有类。
最好自己循环设置并使用-isKindOfClass:
作为测试。
IF 您确实想要使用NSPredicate
,但您可以这样做。作为示例,这将过滤从NSString
派生的所有对象的数组。如果您想要严格的班级成员资格,可以将isKindOfClass:
替换为isMemberOfClass:
。
集合中所有对象实现的任何选择器,接受一个参数并返回BOOL
应该可以正常工作。
NSArray *mixedArray = {...};
NSPredicate *predicate = [NSPredicate predicateWithFormat:
@"self isKindOfClass: %@",
[NSString class]];
NSLog(@"%@", [mixedArray filteredArrayUsingPredicate:predicate]);
答案 1 :(得分:25)
从iOS 4和Mac OS 10.6开始,也可以使用+[NSPredicate predicateWithBlock:]
。例如:
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id object, NSDictionary *bindings) {
return [object isKindOfClass:[NSString class]];
}];
这允许您纯粹使用Objective-C表达谓词,而不是predicateWithFormat:
所需的谓词语法。
答案 2 :(得分:22)
您可以向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没有这种方法,因此需要一个类别。