通过将新项目保存到具有继承的过滤获取请求的CoreData错误
Posted
技术标签:
【中文标题】通过将新项目保存到具有继承的过滤获取请求的CoreData错误【英文标题】:CoreData error by saving new item to filtered fetch request with inheritance 【发布时间】:2015-10-21 23:01:23 【问题描述】:我已经使用实体继承设置了我的核心数据模型(A 是 X 和 Y 的父实体)。通过执行获取请求,我有一个谓词来过滤子实体 (X) 的属性。
这是我的获取请求:
func fetchRequest() -> NSFetchRequest
let fetchRequest = NSFetchRequest(entityName: "A")
let predicate = NSPredicate(format: "test == %@", "123")
fetchRequest.predicate = predicate
fetchRequest.includesSubentities = true
return fetchRequest
注意:“test”是X的一个属性。
现在,当我尝试添加新的子项(Y 类型)时,我的应用程序崩溃并引发以下错误:
CoreData:错误:严重的应用程序错误。在核心数据更改处理期间捕获到异常。这通常是 NSManagedObjectContextObjectsDidChangeNotification 观察者中的一个错误。 [<...> valueForUndefinedKey:]:实体 Y 不符合键“test”的键值编码。与用户信息 ... NSUnknownUserInfoKey = 测试;
【问题讨论】:
【参考方案1】:您正在获取的实体(“A”及其子实体)与谓词不匹配,该谓词正在测试仅存在于其中一个子实体(“X”)上的属性。
当你只有“X”时一切都很好,但是一旦你创建了一个“Y”对象,FRC 就会看到它,检查实体是否匹配它的底层获取(它会这样做,因为“Y”是“A”的子实体)。然后它会测试“Y”对象是否与谓词匹配,并发现它没有test
属性。因此它抛出异常。
由于只有“X”对象可以匹配谓词,您应该修改 fetch 以使用“X”实体:
let fetchRequest = NSFetchRequest(entityName: "X")
【讨论】:
在我的请求中,我使用上述谓词获取 X 实体和 Y 实体。效果很好。【参考方案2】:该错误通常是由于 NSFetchedResultsControllerDelegate
中的崩溃或某些核心数据更改之一的观察者造成的。您应该添加转到断点导航器(Command-7),单击断点导航器区域底部的小加号,然后选择“添加异常断点...”。这应该会导致调试器在引发异常时暂停应用程序,以便您可以具体查看哪段代码有问题。
【讨论】:
调试器通过保存核心数据停止:尝试 managedObjectContext.save()【参考方案3】:对于那些对可能的解决方案感兴趣的人: 我通过删除 fetchRequest 谓词并创建自己的过滤函数避免了这个问题。
【讨论】:
以上是关于通过将新项目保存到具有继承的过滤获取请求的CoreData错误的主要内容,如果未能解决你的问题,请参考以下文章
如何通过 NSPredicate 过滤 Core Data 托管对象?