2

我有一个简短的问题。我有一个NSArray填充Cars(继承自 NSObject)。 Car@property NSString *engine(也被视为@synthesize

现在我想使用以下方法过滤数组NSPredicate

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

这会引发valueForUndefinedKey错误。是predicateWithFormat正确的吗?

感谢您的回复。

4

4 回答 4

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:很聪明。它看到“啊哈,一个%@替换模式!这意味着我可以从参数列表中弹出一个参数并将它装箱并按原样使用它”。这正是它要做的。searchText它将从参数列表中弹出 的值,将其放入一个 中NSExpression,然后将其直接插入到已解析的表达式树中。

这里最有趣的是它创建的表达式将是一个常量值表达式。这意味着它是一个字面值;不是关键路径,不是集合等。它将是文字字符串。然后,当您的谓词运行时,它将执行以下操作:

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

这是正确的,也是为什么stringWithFormat:在将内容传递给predicateWithFormat:.

于 2011-09-26T16:54:25.580 回答
3

k,我发现了错误。

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

工作正常。** 不见了。此外,您的 searchText 应该是大写的。

@Josuhua 这不是真正的代码,只是为了可视化我的问题

于 2010-03-24T11:22:45.170 回答
2

首先,您的代码比必要的更冗长,这总是让您面临错误的可能性。尝试:

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

其次,“ArrayWithCars”看起来像一个类名(按照惯例,类以大写字母开头)。它实际上是一个类还是一个命名不当的局部变量(例如:“arrayWithCars”或只是“cars”)?

第三,确切的错误是什么?什么键未定义?向他人寻求帮助时不要解释错误 - 除非您向我们展示,否则我们无法看到您所看到的内容。

于 2010-03-24T11:19:13.953 回答
1

试试这个链接。你可能知道使用NSPredicate的不同方式

于 2011-09-26T10:38:18.333 回答