1

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

苹果文件表示这是取消注册KVO的正确地点。

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

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

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

回答

0

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

3

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

对我来说,解决办法是改变删除规则对于A级联,这样,当一个对象删除了prepareForDeletion注销用于KVO B对象删除了。这很重要,因为删除A仍然会导致B的反比关系设置为零之前B实际上被删除。

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

+0

良好的观察(虽然来自硬敲门学院)。 – 2016-09-17 23:19:47