在不同对象的数组中搜索
Search in array of different objects
我正在为我的谓词搜索而苦苦挣扎,可能是缺乏词汇。
我这里有一个(有点)弱的设计,我的截止日期不允许我改变得太深,情况如下。
我正在 contacts
和 users
的表格视图中搜索,这是我关注的两个对象。当只有联系人(并且 none 列出的对象是用户时,搜索工作正常。
现在,如果碰巧(这种情况经常发生)其中一些联系人是用户,当我搜索 tableview 时,我的谓词键不匹配,我显然会遇到异常。
我知道我希望搜索仍然包括所有人,我怎么能继续解决这个问题。 (我有一个备份计划,我只是将用户从搜索功能中删除,它就像一个魅力)。
我试过在我的谓词中使用 OR,就像这样:
@"compositeName contains[c] %@ OR name contains[c] %@" //(where %@ is my search string)
但是跳过我的联系人有 "compositeName" 而我的用户有 "name" 的事实是不够的,这会导致异常。
我不想将我的用户的密钥名称修改为 "compositeName",因为这意味着要为我所有的 Beta 测试人员重新安装应用程序,这是(由于截止日期和应用程序生成的内容)也不可能。除非有一种方法让他们无需重新安装就可以拥有新的数据模型,否则我会这样做并简单地将它们全部命名为 "compositeName"。 (或 "name")。
我正在使用核心数据,数组中充满了 NSManagedObject(用户和联系人类型)。
有什么想法吗?
编辑 1:这是个好主意吗?
如果有用户,我正在考虑拆分数组,然后在两者中使用不同的谓词,最后再次组合它们并显示这些结果。但似乎处理了很多,也许还有更高效的方法?
编辑 2:崩溃日志
*** 由于未捕获的异常 'NSUnknownKeyException' 而终止应用程序,原因:“[valueForUndefinedKey:]:实体用户不符合键 "compositeName" 的键值编码。”
编辑 3:Class 检查
根据堆栈上的评论和其他帖子,您实际上可以添加条件检查,并在谓词中进行 class 检查。现在我试图通过写这个来结合两者:
@"((className == %@) name contains[c] %@) OR ((className == %@) compositeName contains[c] %@)", @"User",searchText, @"Contact", searchText
格式不正确。这是我第一次玩谓词所以如果你有任何线索如何写一个说
的谓词
(If class = User, then name contains [c], if class = Contact, then compositeName contains [c])
您的问题是您的组合谓词将针对每个对象的两个属性发送 valueForKey
- 并且给定对象仅支持两个属性中的一个,因此您得到异常。
如果您将使用 AND 的对象 class 测试与 name/compositeName 测试组合,您可以避免此问题 - 通过首先测试 class,谓词将跳过第二个测试(对于 name/compositeName)因为第一个测试已经返回 false - 使得检查 AND 的第二个子句变得毫无意义。
您可以使用类似
的谓词
@"(className == %@ AND name contains[c] %@) OR (className == %@ AND compositeName contains[c] %@)",[User className],searchString,[Contact classname],searchString
我正在为我的谓词搜索而苦苦挣扎,可能是缺乏词汇。
我这里有一个(有点)弱的设计,我的截止日期不允许我改变得太深,情况如下。
我正在 contacts
和 users
的表格视图中搜索,这是我关注的两个对象。当只有联系人(并且 none 列出的对象是用户时,搜索工作正常。
现在,如果碰巧(这种情况经常发生)其中一些联系人是用户,当我搜索 tableview 时,我的谓词键不匹配,我显然会遇到异常。
我知道我希望搜索仍然包括所有人,我怎么能继续解决这个问题。 (我有一个备份计划,我只是将用户从搜索功能中删除,它就像一个魅力)。
我试过在我的谓词中使用 OR,就像这样:
@"compositeName contains[c] %@ OR name contains[c] %@" //(where %@ is my search string)
但是跳过我的联系人有 "compositeName" 而我的用户有 "name" 的事实是不够的,这会导致异常。
我不想将我的用户的密钥名称修改为 "compositeName",因为这意味着要为我所有的 Beta 测试人员重新安装应用程序,这是(由于截止日期和应用程序生成的内容)也不可能。除非有一种方法让他们无需重新安装就可以拥有新的数据模型,否则我会这样做并简单地将它们全部命名为 "compositeName"。 (或 "name")。
我正在使用核心数据,数组中充满了 NSManagedObject(用户和联系人类型)。
有什么想法吗?
编辑 1:这是个好主意吗?
如果有用户,我正在考虑拆分数组,然后在两者中使用不同的谓词,最后再次组合它们并显示这些结果。但似乎处理了很多,也许还有更高效的方法?
编辑 2:崩溃日志
*** 由于未捕获的异常 'NSUnknownKeyException' 而终止应用程序,原因:“[valueForUndefinedKey:]:实体用户不符合键 "compositeName" 的键值编码。”
编辑 3:Class 检查
根据堆栈上的评论和其他帖子,您实际上可以添加条件检查,并在谓词中进行 class 检查。现在我试图通过写这个来结合两者:
@"((className == %@) name contains[c] %@) OR ((className == %@) compositeName contains[c] %@)", @"User",searchText, @"Contact", searchText
格式不正确。这是我第一次玩谓词所以如果你有任何线索如何写一个说
的谓词(If class = User, then name contains [c], if class = Contact, then compositeName contains [c])
您的问题是您的组合谓词将针对每个对象的两个属性发送 valueForKey
- 并且给定对象仅支持两个属性中的一个,因此您得到异常。
如果您将使用 AND 的对象 class 测试与 name/compositeName 测试组合,您可以避免此问题 - 通过首先测试 class,谓词将跳过第二个测试(对于 name/compositeName)因为第一个测试已经返回 false - 使得检查 AND 的第二个子句变得毫无意义。
您可以使用类似
的谓词@"(className == %@ AND name contains[c] %@) OR (className == %@ AND compositeName contains[c] %@)",[User className],searchString,[Contact classname],searchString