尝试取消与已删除实体的关系时,Core Data崩溃

时间:2013-02-25 16:09:26

标签: ios objective-c core-data

构建讨论框架:

  • 两个托管对象实体A和B
  • A和B彼此具有一对一的反比关系
  • 该关系的两个方向都有一个Nullify删除规则

问题:经过一段时间后,我正在编组实体A的实例,我尝试将关系更改为newB(之前与oldB有关系)(例如AB = newB),我得到了一个核心数据例外:

  

CoreData无法解决'0x1e1515a0 x-coredata:// 90361082-A433-41A0-9F4E-BA3F032B193D / oldB / p7'

从我的研究和测试中,我收到此错误,因为引用的oldB实体已被删除且不再可用于核心数据。 (我相信)异常被抛出,因为Core Data试图访问oldB以使与A的关系无效,但显然不能因为oldB消失了。

我不明白的是我是如何/为什么进入这种状态,因为当我(在代码执行之前的某个时间)执行 removeObject: oldB时,Core Data应该已经无效关系所以当我执行上述操作时,我预计AB == nil已经。

我会说这绝对在绝大多数情况下似乎都能正常运作。但是,当发生这种情况时,在删除/恢复数据库之前,应用程序将完全无法使用。


所以,我希望回答几个问题:

  • 为什么会这样?是否有可能这是开发工作的影响(例如,可能在removeObject之前杀死进程:oldB完成等),这在生产中不一定会发生?
  • 我的恢复选项是什么?我想我可以使用@try和@catch异常处理程序,但是我不确定它是否会在最后产生影响,因为在@catch处理程序中会发生同样的问题,除非有一些核心数据技巧我是不知道“强制杀死”这种关系(我认为不存在这种关系,因为它在技术上会打破数据图)。
  • 对于我的数据图,A和B之间的关系是“松散的”并且并不重要(实际上B对象在完成其工作后被删除)。因为我有一个独立于A的B的清理过程,我最好只使用“无操作”删除策略,以便在这些罕见的情况下Core Data不会窒息吗?

我感谢您提前获得的任何见解!


更新:

我一直在玩一些@try和@catch块。这是我一直在寻找的:

@try {
 if (A.B.A) // Relationship check. Will throw exception if B is missing
  nil;
 }
@catch {
 [moc deleteObject:A.B];
 [moc save:nil];
 }

在上面的例子中,运行了@catch代码,但在保存时,Core Data会抛出一个注释:

  

注释:修复对象A上的一对一关系B的缺失删除传播

然后我尝试继续使用我的代码,当我再次尝试更改A.B时,我就回到了故障异常的开始位置。

所以,我尝试将@catch块更改为:

@catch {
 [moc deleteObject:A.B];
 A.B = nil;
 [moc save:nil];
}

有趣的是deleteObject和设置A.B = nil工作,但保存时,抛出原始异常:

  

CoreData无法解决'0x2009b1e0 x-coredata:// 90361082-A433-41A0-9F4E-BA3F032B193D / B / p10'的错误

因此,在这种情况下我可以做的很少,因为Core Data通过不惜一切代价维护对象图来完成它的工作(包括运行应用程序的能力!)。

没有重新启动整个数据存储,有什么建议吗?

1 个答案:

答案 0 :(得分:2)

我能够通过删除catch块中的两个 A和B来解决这个问题:

@try {
 if (A.B.A) // Relationship check. Will throw exception if B is missing
  nil;
 }
@catch {
 [moc deleteObject:A.B];
 [moc deleteObject:A];
 [moc save:nil];
 }

然而,这并不理想,因为A很重要(B不是)。幸运的是,A可以以远低于丢失整个对象图的成本重新生成。为了工作生产代码,我认为这个解决方案是合适的,但并不理想。

仍然会喜欢能够保存实体A的答案......