【发布时间】:2013-02-25 16:09:26
【问题描述】:
框架讨论:
- 两个托管对象实体,A 和 B
- A 和 B 之间存在一对一的反向关系
- 关系的两个方向都有一个无效删除规则
问题:一段时间后,我正在通过实体 A 的实例进行编组,并尝试将关系更改为 newB(一段时间后与 oldB 建立了关系)(例如 A.B = newB),我得到了核心数据异常:
CoreData 无法满足“0x1e1515a0 x-coredata://90361082-A433-41A0-9F4E-BA3F032B193D/oldB/p7”的错误
根据我的研究和测试,我收到此错误是因为引用的 oldB 实体已删除并且不再可用于核心数据。 (我相信)抛出异常是因为 Core Data 试图访问 oldB 以使与 A 的关系无效,但显然不能,因为 oldB 已经消失了。
我不明白我是如何/为什么进入这种状态的,因为当我(在代码执行之前的某个时间)执行 removeObject: oldB 时,Core Data 应该已经无效这种关系,所以当我执行上述操作时,我希望 A.B == 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 不惜一切代价维护对象图(包括运行应用程序的能力!)。
没有重新初始化整个数据存储,有什么建议吗?
【问题讨论】:
-
A 的实体是否具有与 B 的关系的自定义设置器?您是否在任何地方观察到这种关系?
-
不,我对 getter/setter 使用标准的 NSManagedObject @dynamic 属性。我的任何代码都不会通过 KVO 监控这种关系。
-
我不确定发生了什么,但 FWIW,删除 B 不会使 A.B == nil 直到您保存更改。在那之前它仍然指向旧的 B。
-
@TomHarrington 那么,如果我的视图取决于我的模型并且如果删除一个实体,我是否必须保存?我以为我可以让用户在他想要的时候保存,但由于这条规则(删除不会在保存之前无效),我的模型是不连贯的。
-
我已就此事向相关主题开放:stackoverflow.com/questions/17158091/…
标签: ios objective-c core-data