NSPredicate 无法解析格式字符串

Posted

技术标签:

【中文标题】NSPredicate 无法解析格式字符串【英文标题】:NSPredicate unable to parse format string 【发布时间】:2015-06-30 03:02:18 【问题描述】:

我看不出这行代码有什么问题。为什么解析不了?

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

日志也无济于事。

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

编辑 1:

好的,predicateWithFormat 似乎不理解“%1$@”。我把它切换到

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

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

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

由于未捕获的异常“NSUnknownKeyException”而终止应用程序, 原因:'[valueForUndefinedKey:]:实体用户是 不符合键“a”的键值编码。'

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

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

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 的更好。

【问题讨论】:

【参考方案1】:

你可以这样做:

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

【讨论】:

完美运行!这就是我需要的。谢谢【参考方案2】:

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

【讨论】:

哎呀!这也有效。但我只是接受了伊万的回答。很抱歉。 对我来说最好的答案。【参考方案3】:

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

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

【讨论】:

我有点知道。有什么办法吗?因为我所有的 searchString 都是相同的值... ***.com/questions/7536750/… 看看这个... 我不想使用复合谓词,因为我的谓词不太复杂。

以上是关于NSPredicate 无法解析格式字符串的主要内容,如果未能解决你的问题,请参考以下文章

使用撇号时无法解析格式字符串 nspredicate 错误

ios:使用 NSPredicate 检查正则表达式 - 无法解析格式字符串

为啥我收到“无法解析 NSPredicate”错误

无法解析 RealmSwift 中的格式字符串

过滤字典数组时无法解析格式字符串?

核心数据谓词根据关系获取数据,错误为无法解析格式字符串