2

为什么[MyClass class]无法在谓词中找到我想要的类的对象而[myObject class]工作?请参阅下面的代码示例。我希望能够在集合中找到 MyClass 类型的对象,而无需提供该类的虚假实例。

MyClass* myObject = [[MyClass alloc] init];

这行不通...

NSPredicate* predicate = [NSPredicate predicateWithFormat:@"self isMemberOfClass: %@", [MyClass class]];
NSArray* predicateResults = [mySet filteredSetUsingPredicate:predicate].allObjects;

这确实有效...

NSPredicate* predicate = [NSPredicate predicateWithFormat:@"self isMemberOfClass: %@", [myObject class]];
NSArray* predicateResults = [mySet filteredSetUsingPredicate:predicate].allObjects;
4

2 回答 2

14

像这样的谓词

[NSPredicate predicateWithFormat:@"self isMemberOfClass: %@", [MyClass class]]

确实有效。它返回与(记录的)完全相同的谓词

[NSComparisonPredicate
    predicateWithLeftExpression:[NSExpression expressionForEvaluatedObject]
                rightExpression:[NSExpression expressionForConstantValue:[MyClass class]]
                 customSelector:@selector(isMemberOfClass:)]

在您的情况下,问题可能是isMemberOfClass: 比较类相等性,因此这将不匹配作为 的子类成员的对象MyClass

如果MyClass是类集群并且myObject是具体子类的实例,则可能会发生这种情况。例如:

NSString *myString = [[NSString alloc] initWithUTF8String:"hello world"];
Class c1 = [NSString class];   //  NSString
Class c2 = [myString class];   //  __NSCFString

BOOL b1 = [myString isMemberOfClass:c1]; // NO
BOOL b2 = [myString isMemberOfClass:c2]; // YES

在那种情况下[myObject class][MyClass class]是不同的,这可以解释为什么一个谓词有效而另一个谓词无效。

以下代码isKindOfClass:改为使用并产生预期结果:

NSArray *array = @[@"123", @456, [NSArray array]];
NSPredicate* predicate = [NSPredicate predicateWithFormat:@"self isKindOfClass: %@", [NSNumber class]];
NSArray* predicateResults = [array filteredArrayUsingPredicate:predicate];
NSLog(@"%@", predicateResults);
//  Output: ( 456 )
于 2013-08-22T11:11:38.697 回答
4

严格来说不是对您的问题的回答(请参阅 MartinR 的优秀答案),而是根据记录的predicateWithFormat:方法替代(IMO):

你可以predicateWithBlock:用来创建你的NSPredicate,像这样:

NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
    return [evaluatedObject isKindOfClass:[myClass class]];
}];

这应该可以正常工作。

于 2013-08-22T10:31:53.620 回答