NSPredicate无法解析格式字符串

时间:2015-06-30 03:02:18

标签: ios objective-c nspredicate

我看不出这些代码行有任何问题。为什么不能解析?

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

日志也无济于事。

  

由于未捕获的异常而终止应用   'NSInvalidArgumentException',原因:'无法解析格式   string“(用户名CONTAINS [cd]%1 $ @)||(userId CONTAINS [cd]%1 $ @)||   (名字CONTAINS [cd]%1 $ @)|| (姓氏CONTAINS [cd]%1 $ @)“'

修改1:

好吧,看起来似乎谓词谓词不理解“%1 $ @”。我把它切换到

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

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

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

由于未捕获的异常'NSUnknownKeyException'而终止应用,   reason:'[valueForUndefinedKey:]:用户实体   不是密钥值编码兼容键“a”。'

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

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

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];

如果我希望将来扩展搜索字段怎么办?我必须添加更多参数?更多“,searchString,searchString,searchString”?

解决

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

**注意**

Bannings的回答没问题,直到我的搜索字符串包含单引号',然后应用程序崩溃。所以我认为使用Ewan更好。

3 个答案:

答案 0 :(得分:7)

你可以这样做:

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

答案 1 :(得分:3)

尝试将%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];

答案 2 :(得分:0)

您需要为每个变量添加字符串,如果您使用5%@,则需要应用相同的searchString值或其他填充该值的值

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