框架讨论:
- 两个托管对象实体,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 不惜一切代价维护对象图(包括运行应用程序的能力!)。
没有重新初始化整个数据存储,有什么建议吗?