说我有两个NSPredicate
s
NSPredicate *pa = [NSPredicate predicateWithBlock:^(BOOL)(id evaluatedObject, NSDictionary *bindings) {
return [evaluatedObject isKindOfClass:[TestClass class]];
}];
NSPredicate *pb = [NSPredicate predicateWithBlock:^(BOOL)(id evaluatedObject, NSDictionary *bindings) {
return [evaluatedObject isKindOfClass:NSClassFromString(@"TestClass")];
}];
我想要的是,当我将pa
放入NSDictionary
并将其与其他对象关联时,请说obj
,稍后当我使用pb
签入字典时我回来了obj
。
这是怎么回事?
我看到NSPredicate
实现NSCopying
,所以我希望它可以作为密钥。但我对上面概述的案例不太确定。
答案 0 :(得分:2)
是的,您可以将任何对象用作键,只要其类实现NSCopying
。
答案 1 :(得分:2)
NSPredicate
会覆盖 isEqual
,但这似乎只在
非常简单的案例:
NSPredicate *pa = [NSPredicate predicateWithFormat:@"foo = 'bar'"];
NSPredicate *pb = [NSPredicate predicateWithFormat:@"foo = 'bar'"];
BOOL b = [pa isEqual:pb]; // --> YES
在这种情况下,您可以使用键pa
将对象放入字典中并获取
使用键pb
返回对象。
但这根本不适用于基于块的谓词,即使它们引用了 同一块:
BOOL (^block)(id evaluatedObject, NSDictionary *bindings) = ^BOOL(id evaluatedObject, NSDictionary *bindings) {
return [evaluatedObject isKindOfClass:[NSString class]];
};
NSPredicate *pa = [NSPredicate predicateWithBlock:block];
NSPredicate *pb = [NSPredicate predicateWithBlock:block];
BOOL b = [pa isEqual:pb]; // --> NO
即使这样可行,但在您的情况下需要两个块 在谓词中被认为是相等的,但事实并非如此:
BOOL (^block1)(id evaluatedObject, NSDictionary *bindings) = ^BOOL(id evaluatedObject, NSDictionary *bindings) {
return [evaluatedObject isKindOfClass:[NSString class]];
};
BOOL (^block2)(id evaluatedObject, NSDictionary *bindings) = ^BOOL(id evaluatedObject, NSDictionary *bindings) {
return [evaluatedObject isKindOfClass:NSClassFromString(@"NSString")];
};
BOOL b = [block1 isEqual:block2]; // --> NO
最后,事实证明两个具有相同主体的块不相等:
BOOL (^block1)(id evaluatedObject, NSDictionary *bindings) = ^BOOL(id evaluatedObject, NSDictionary *bindings) {
return [evaluatedObject isKindOfClass:[NSString class]];
};
BOOL (^block2)(id evaluatedObject, NSDictionary *bindings) = ^BOOL(id evaluatedObject, NSDictionary *bindings) {
return [evaluatedObject isKindOfClass:[NSString class]];
};
BOOL b = [block1 isEqual:block2]; // --> NO
因此,您可以将谓词用作字典中的键,但至少对于基于块的键 谓词这很没用。
答案 2 :(得分:0)
不幸的是,它没有像我预期的那样工作。虽然NSPredicate
实现了NSCopying
,但谓词可以包含任意块的事实应该很明显,实际上不可能可靠地比较两个NSPredicate
。
在我的机器上测试,即使用于查询字典的相同谓词实例也不会返回先前的设置值。我的猜测是,当字典获取谓词时,它会复制它,并且因为isEqual:
的{{1}}的实现可能仅在相等的指针上返回true,原始谓词实例与其副本相比也返回false。