通过将新项目保存到具有继承的过滤获取请求的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 托管对象?

Spring Cloud Zuul 实现路由,获取参数

如何过滤在 Core Data 中有对象的表视图?

将可转换的 NSAttributedString 保存到 Core Data 时出现异常奇怪的崩溃

使用 EF Core 过滤包含时的列名无效

Core Data 中的并发获取请求