willTurnIntoFault不止一次被调用,导致崩溃

时间:2010-11-23 08:44:00

标签: core-data nsmanagedobject nsundomanager key-value-observing

NSManagedObject的子类中,在撤消最初创建相关对象的某些代码时,我的被覆盖的willTurnIntoFault实现被调用了两次。当尝试在密钥路径上双重注销KVO时,这会导致崩溃。

Apple文件称这是取消注册KVO的正确位置。

一些上下文 - 撤消操作涉及从其超级视图中删除模型的相应视图。视图保留了它的模型。

所以我的问题是:什么样的程序员错误会导致willTurnIntoFault的子类中NSManagedObject被调用两次?

注意:以前我在这个类中覆盖dealloc,但后来意识到这不建议用于NSManagedObject的子类。我已将此代码移至-didTurnIntoFault。我目前还没有覆盖Apple文档说你不应该覆盖的任何其他方法。

2 个答案:

答案 0 :(得分:3)

为了后人的缘故:我遇到了同样的问题。在我的情况下,我有一个对象 A 与对象 B 的(一对一)关系。当 A 被删除时 B A 的反向关系设置为null。这导致 B observeValueOfKeyPath:ofObject:change:context方法被调用(其中keypath B A 的关系。不幸的是,这个方法检查了 A 的属性,导致 A 的错误被取消(请注意,在这种情况下awakeFromFetch不会被调用 - 我认为因为对象从未真正进入故障状态)。因此,我可能会稍后再次调用willTurnIntoFault并且该对象将再次尝试取消注册KVO,从而导致崩溃 - 就像在OP中一样。

对我来说,解决方案是将A的删除规则更改为级联,以便在A对象被删除 AND 时取消B对象以取消注册prepareForDeletion中的KVO。这很重要,因为删除 A 仍会导致 B 的反向关系在实际删除 B 之前设置为nil。

请注意,prepareForDeletion会在之前调用,而不会在willTurnIntoFault之前调用。因此,如果您在两者中取消注册KVO,则需要保持某种状态以确保您尚未注册。

答案 1 :(得分:0)

似乎问题是由自定义setter方法引起的,该方法是在willTurnIntoFault中设置/取消设置KVO值。