這裏是真正的原因,它不工作的方式不同:
當你建立一個使用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:
傳遞的東西。
正確。包含'stringWithFormat:'是導致問題的原因。請參閱我的答案以獲得完整的解釋。 – 2011-09-26 16:54:57