1

框架讨论:

  • 两个托管对象实体,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 的缺失删除传播

然后我尝试继续执行我的代码,当我再次尝试更改 AB 时,我又回到了错误异常开始的地方。

因此,我尝试将 @catch 块更改为:

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

有趣的是,deleteObject 和设置 AB = nil 有效,但是在保存时,会抛出原始异常:

CoreData 无法满足“0x2009b1e0 x-coredata://90361082-A433-41A0-9F4E-BA3F032B193D/B/p10”的错误

因此,在这种情况下,我似乎无能为力,因为 Core Data 不惜一切代价维护对象图(包括运行应用程序的能力!)。

没有重新初始化整个数据存储,有什么建议吗?

4

1 回答 1

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 的答案......

于 2013-02-26T14:31:29.447 回答