这是它不起作用的真正原因:
当您使用 构建字符串时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:
很聪明。它看到“啊哈,一个%@
替换模式!这意味着我可以从参数列表中弹出一个参数并将它装箱并按原样使用它”。这正是它要做的。searchText
它将从参数列表中弹出 的值,将其放入一个 中NSExpression
,然后将其直接插入到已解析的表达式树中。
这里最有趣的是它创建的表达式将是一个常量值表达式。这意味着它是一个字面值;不是关键路径,不是集合等。它将是文字字符串。然后,当您的谓词运行时,它将执行以下操作:
id leftValue = [object valueForKey:@"engine"];
id rightValue = [rightExpression constantValue];
return (leftValue is like rightValue);
这是正确的,这也是为什么stringWithFormat:
在将内容传递给predicateWithFormat:
.