CoreData 在后台 MOC 的保存操作期间无法完成故障

Posted

技术标签:

【中文标题】CoreData 在后台 MOC 的保存操作期间无法完成故障【英文标题】:CoreData can't fulfill a fault during save operation from background MOC 【发布时间】:2014-12-31 09:29:10 【问题描述】:

我正在使用两个 MOC,一个用于主线程,另一个 MOC 用于后台线程。 在主线程上,我有一个使用 FRC (NSFetchedResultsController) 的 UITableView。

偶尔我会运行一个大规模的保存操作,删除所有对象并构建数百个新对象...此时我想在主线程中的 UITableView 刷新其数据(显然使用 FRC) .因此,主 MOC 注册到 NSManagedObjectContextDidSaveNotification 通知(从后台 MOC 接收)并在该阶段运行 mergeChangesFromContextDidSaveNotification 以确保 UITableView 相应地更新。

这一切正常,直到我在保存操作期间尝试滚动 UITableView。当我尝试滚动视图时,会引发“coredata 无法完成错误”异常。这是 FRC 仍然持有已删除对象的结果(虽然保存操作仍在运行,但在主 MOC 上收到来自 NSManagedObjectContextDidSaveNotification 通知的 mergeChangesFromContextDidSaveNotification 之前)。 这是保存操作和收到 mergeChangesFromContextDidSaveNotification 后 UITableView 更新之间的某种“竞争条件”。

与这两个 MOC 合作并照顾 FRC 以使其能够应对这种情况的正确方法是什么?

【问题讨论】:

【参考方案1】:

根据apples doc:

无法实现故障 问题:您看到错误消息“核心 数据无法完成错误”。

原因:对应对象的底层数据已被删除 来自持久存储。

补救措施:你应该丢弃这个对象。

至少在两种情况下会出现此问题:

第一:

从对托管对象的强引用开始。删除托管 对象通过托管对象上下文。保存对对象的更改 语境。至此,被删除的对象已经变成了一个 过错。它不会被销毁,因为这样做会违反规则 内存管理。

尝试从之前检索到的属性或关系 保留参考。 Core Data 将尝试对有故障的托管服务进行故障排除 对象,但不会这样做,因为该对象已从 商店。即不再存在具有相同全局的对象 店内身份证。

第二:

从托管对象上下文中删除一个对象。未能打破所有 从其他对象到该对象的关系。保存更改。

【讨论】:

谢谢。我读过这篇文章......考虑到我描述的“丢弃这个对象”的架构和场景,最好的方法是什么?

以上是关于CoreData 在后台 MOC 的保存操作期间无法完成故障的主要内容,如果未能解决你的问题,请参考以下文章

如何通知主 MOC,后台 MOC 的变化

CoreData SIGABRT 同时保存主 MOC。为啥?

带有 3 MOC 解决方案的 Ios CoreData(应用程序在保存过程中冻结)

RestKit CoreData 0.20.3 - 映射完成后保存 MOC 之前的额外检查

我无法使用非主 MOC 在后台线程上创建 NSManagedObject 的新实例

核心数据 MOC 保存暂停执行并且无法保存(无错误或崩溃)