2010-03-24 55 views
2

我有一個簡短的問題。我有一個NSArray填充Cars(從NSObject繼承)。 Car@property NSString *engine(也算是@synthesizeNSPredicate和數組

現在我想用NSPredicate的濾鏡陣列:

predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"(engine like %@)", searchText]]; 
newArray = [ArrayWithCars filteredArrayUsingPredicate:predicate]; 

這引發valueForUndefinedKey錯誤。 predicateWithFormat正確嗎?

感謝您的回覆。

回答

2

首先,你的代碼比必要的更冗長,這總是會讓你意識到錯誤的可能性。嘗試:

predicate = [NSPredicate predicateWithFormat:@"engine like %@", searchText]; 

其次,「ArrayWithCars」看起來像一個類名(按照慣例,類以大寫開頭)。它實際上是一個類或一個不正確的名稱局部變量(例如:「arrayWithCars」或只是「汽車」)?

三,確切的錯誤是什麼?什麼關鍵是未定義的?請求別人幫忙時不要錯過錯誤 - 除非您向我們展示,否則我們無法看到您所看到的內容。

+0

正確。包含'stringWithFormat:'是導致問題的原因。請參閱我的答案以獲得完整的解釋。 – 2011-09-26 16:54:57

3

k,我發現了錯誤。

predicate = [NSPredicate predicateWithFormat:@"engine like *%@*", searchText]; 

工作正確。 **失蹤了。另外你的searchText應該是大寫的。

@Josuhua 這不是真正的代碼,只是爲了形象化我的問題

+0

bend0r:不要摺疊琴絃;當你需要比較字符串不區分大小寫時,請使用不區分大小寫的比較。在這種情況下,就是'LIKE [c]'。 – 2010-03-24 16:03:31

+0

發佈除您正在使用的代碼以外的代碼通常不會幫助其他人幫助您。 – 2010-03-24 16:40:28

1

與此link.試試你可能知道使用NSPredicate

4

這裏是真正的原因,它不工作的方式不同:

當你建立一個使用stringWithFormat:一個字符串,它要來這樣看:

@"engine like searchText" 

然後你把它傳遞給predicateWithFormat:,這是會看到,無論是左手側和比較的右邊是未加引號字符串,這意味着它要理解他們,如果他們keypaths

運行此代碼時,它會做:

id leftValue = [object valueForKey:@"engine"]; 
id rightValue = [object valueForKey:@"searchText"]; 
return (leftValue is like rightValue); 

得到拋出的異常是你的對象抱怨說,它並沒有一個名爲「SEARCHTEXT」的方法,這是正確的。

與此相反的,如果你拿出stringWithFormat:電話,只是把一切都直接進入predicateWithFormat:

NSPredicate *p = [NSPredicate predicateWithFormat:@"engine like %@", searchText]; 

predicateWithFormat:是聰明的。它看到「aha,一個%@替換模式!這意味着我可以從參數列表中彈出一個參數並將其裝箱並按原樣使用它」。這正是它要做的。它會從參數列表中彈出searchText的值,將其放在NSExpression中,並將其直接插入解析的表達式樹中。

這裏最有意思的是,它創建的表達式將是一個常數值表達式。這意味着它是一個字面值;不是關鍵路徑,也不是集合等。它將是字面字符串。然後,當你的謂詞運行時,它會做:

id leftValue = [object valueForKey:@"engine"]; 
id rightValue = [rightExpression constantValue]; 
return (leftValue is like rightValue); 

而且是正確的,也是爲什麼你不應該把它傳遞給predicateWithFormat:之前通過stringWithFormat:傳遞的東西。