2013-08-21 84 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。

相關問題