2011-07-17 132 views
7

虽然基于用户输入过滤我的NSMutableDictionary工作,我创建了下面的代码:NSPredicate predicateWithFormat:(NSString *)不一致?

NSString *predicateString = [NSString stringWithFormat:@"SELF beginsWith[cd] %@", searchString]; 
NSPredicate *pred = [NSPredicate predicateWithFormat:predicateString]; 
NSArray *filteredKeys = [[myMutableDictionary allKeys] filteredArrayUsingPredicate:pred]; 

“搜索字符串”传递到这个定义的方法:

(NSString*) searchString 

然而,这导致以下例外情况如下:

... raise [valueForUndefinedKey:]:该类别为 对于ke不符合密钥值Y ...

的修复竟然是:

NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF beginsWith[cd] %@", searchString]; 
NSArray *filteredKeys = [[myMutableDictionary allKeys] filteredArrayUsingPredicate:pred]; 

我不明白,这就是为什么后者的工作,和前抛出异常。我已阅读key value coding一点点,但我不明白它在这里如何适用。 (即只是通过改变NSPredicate的定义)有人能够启发我吗?

更新: 为了回应jtbandes评论,我继续创建了一个TestApp项目来演示此问题。 http://dl.dropbox.com/u/401317/TestApp1.tar.gz

+0

如果你希望我们弄清楚它的含义,你将不得不向我们展示整个异常。 – jtbandes

回答

17

答案是in the predicate programming guide

字符串常量必须表达单引号和双引号内引用都是可以接受的,...... 如果使用变量替换使用%@ ...,引号都自动为您添加。如果您使用格式字符串中的字符串常量,必须引用他们自己

[我的重点]

predicateWithFormat放入你的报价,但stringWithFormat没有。你的第一个例子可能会工作,如果你这样做:

NSString *predicateString = [NSString stringWithFormat:@"SELF beginsWith[cd] '%@'", searchString]; 
//                   ^^ single or double quotes 
+0

确实,引号解决了这个问题。抛出一个“valueForUndefinedKey”异常就好像把开发人员引向错误的路径。 (无效的谓词语法会更好,我认为)也许这只是我对objective-c的缺乏经验。 – yanigisawa

+0

@yanigisawa:虽然它不是无效的语法。如果没有引号,则认为它是KVC密钥,因此您将一个密钥的值与另一个密钥的值进行比较。在这种情况下,这种例外是有道理的。 – JeremyP

+0

好的,我会把它记下来,因为我对这些编译器和运行时错误没有经验。谢谢你的帮助。 – yanigisawa