NSPredicate无法parsing格式string

我看不到这些代码行有任何问题。 为什么不能parsing?

[NSPredicate predicateWithFormat:@"(username CONTAINS[cd] %1$@) || " "(userId CONTAINS[cd] %1$@) || " "(firstname CONTAINS[cd] %1$@) || " "(lastname CONTAINS[cd] %1$@)", searchString]" 

日志也没有帮助。

终止由于未捕获的exception'NSInvalidArgumentException'的应用程序,原因:'无法parsing格式string'(用户名CONTAINS [cd]%1 $ @)||(用户名CONTAINS [cd]%1 $ @)||(名字CONTAINS [ cd]%1 $ @)||(姓氏CONTAINS [cd]%1 $ @)“'

编辑1:

好的,看起来像predicateWithFormat不明白“%1 $ @”。 我把它切换到

 [... predicateWithFormat:[NSString stringWithFormat:...]] // (same format as above) 

它通过了线路。 但是,下一个问题是:

 self.filteredUserList = [self.userList filteredArrayUsingPredicate:predicate]; 

终止应用程序由于未捕获的exception“NSUnknownKeyException”,原因:'[valueForUndefinedKey:]:实体用户不是密钥值符合密钥“a”。

“a”是我在searchTextBox中input的关键字。 WUT?

我在debugging控制台中打印出谓词,看起来没有错:

 username CONTAINS[cd] a OR userId CONTAINS[cd] a OR firstname CONTAINS[cd] a OR lastname CONTAINS[cd] a 

编辑2:

好的,这个超级难看的代码解决了问题:

 [NSPredicate predicateWithFormat:@"(username CONTAINS[cd] %@) || " "(userId CONTAINS[cd] %@) || " "(firstname CONTAINS[cd] %@) || " "(lastname CONTAINS[cd] %@)", searchString, searchString, searchString, searchString]; 

如果我想在未来扩大search领域呢? 我必须添加更多的参数? 更多“,searchstring,searchstring,searchstring”?

解决了

感谢Ewan和Bannings,给我的问题提供了两个选项。 我testing了他们两个,他们工作liek魅力。 有人可以解释这两者之间的差异,在这种情况下,我应该使用哪个选项?

** 注意 **

Bannings的答案是正确的,直到我的searchstring包含单引号' ,然后应用程序崩溃。 所以我觉得使用Ewan的更好。

你可以这样做:

 [[NSPredicate predicateWithFormat:@"(username CONTAINS[cd] $str) || ..."] predicateWithSubstitutionVariables:@{@"str": searchString}]; 

尝试将%1$@更改为'%1$@'

 NSString *formatString = [NSString stringWithFormat:@"(username CONTAINS[cd] '%1$@') || (userId CONTAINS[cd] '%1$@') || (firstname CONTAINS[cd] '%1$@') || (lastname CONTAINS[cd] '%1$@')", searchString]; NSPredicate *predicate = [NSPredicate predicateWithFormat:formatString]; 

您需要为每个variables添加string,如果您使用5%@,则需要应用相同的searchString值或填充该%@的另一个值

 [NSPredicate predicateWithFormat:@"(username CONTAINS[cd] %1$@) || (userId CONTAINS[cd] %1$@) || (firstname CONTAINS[cd] %1$@) || (lastname CONTAINS[cd] %1$@)", searchString1,searchString2,searchString3,searchString4]