2013-08-21 44 views
2

说我有两个NSPredicate小号我可以使用NSPredicate关键在NSDictionary中

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")]; 
}]; 

我想的是,当我把paNSDictionary,并与其他对象关联,说obj,后来当我检查字典使用pb我找回obj

它是如何工作的?

我看到NSPredicate implements NSCopying,所以我希望它可以作为一个关键。但我不确定上述情况。

+0

检查这个问题http://stackoverflow.com/questions/730076/using-class-as-key-in-nsdictionary –

+1

@ValentinShamardin非sequitur,这与这个问题无关。 – 2013-08-21 05:47:53

回答

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 

而且即使会的工作,它需要你的情况是, 2 在谓词被识别为相等,这不是这种情况:

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 

最后原来塔t双块具有相同体是不相等的:

​​

所以,你可以使用一个谓词作为字典的关键,但至少基于块的 断言这是相当无用的。

+0

您的测试比我的测试更全面。谢谢! – lynnard

+0

@ yulan6248:不客气。 - 这是一个有趣的问题! –

2

是的,只要其类实现NSCopying,就可以使用任何对象作为关键字。

+0

但它真的按照我的预期工作吗?一个类可能实现'',但不会覆盖'isEqual:';如果'NSPredicate'属实,那么在字典中使用它就没用了,因为只有完全相同的实例才会返回先前设置的值。 – lynnard

+1

@ yulan6248这是可能的,但不太可能。从概念上说,可复制性意味着两个对象的定义是明确的,而且容易定义。事实上,如果有人让他们的类符合'NSCopying',但他们不会重写'isEqual:',他们应该被婊子sla sla。 (但是,嘿,你为什么不尝试**呢?) – 2013-08-21 05:45:11

+0

只是自己试了一下。请参阅下面的答案。 – lynnard

0

不幸的是,它不工作,因为我的预期。尽管NSPredicate实现了NSCopying,谓词可以包含任意块的事实应该很明显,实际上不可能比较两个0123.。

在我的机器上测试过,即使是用于查询字典的相同谓词实例也不会返回以前的设置值。我的猜测是,当字典采用谓词时,它会复制它,并且因为NSPredicateisEqual:的实现可能只在相同指针上返回true,所以原始谓词实例与其副本相比也会返回false。

相关问题