代码之家  ›  专栏  ›  技术社区  ›  Andrew Ebling

多次呼叫会变成故障,导致撞车

  •  1
  • Andrew Ebling  · 技术社区  · 15 年前

    NSManagedObject 我的重写实现 willTurnIntoFault 在撤消最初创建所述对象的某些代码时被调用两次。当试图在密钥路径上对KVO进行双重注销时,这会导致崩溃。

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

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

    所以我的问题是: 什么样的程序员错误会导致 意志转变为错误 在的子类中被调用两次 被管理对象 ?

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

    2 回复  |  直到 15 年前
        1
  •  3
  •   edsko    15 年前

    为了子孙后代:我也有同样的问题。在我的情况下,我有一个对象 一个 与一个物体有(对一)关系 . 什么时候? 一个 已被删除 的逆关系 一个 设置为 null . 这导致 observeValueOfKeyPath:ofObject:change:context 要调用的方法(其中 keypath 的关系 一个 ). 不幸的是,此方法检查了 一个 ,导致 一个 取消(注意在这种情况下 awakeFromFetch 不会被调用——我想是因为对象从未真正进入错误状态)。所以我可能会接到第二个电话 willTurnIntoFault 稍后,对象将再次尝试为KVO注销,导致崩溃——就像在OP中一样。

    对我来说,解决方案是将A的删除规则改为级联,这样当A对象被删除时,B对象就被删除了 以及 在中注销KVO prepareForDeletion . 这很重要,因为删除 一个 仍然会导致 之前要设置为零的逆关系 实际上被删除了。

    请注意 准备订单删除 以前打过电话 但不是相反 属于 意志转变为错误 . 因此,如果同时注销KVO,则需要维护一些状态以确保尚未注销。

        2
  •  0
  •   Andrew Ebling    15 年前

    似乎这个问题是由一个自定义setter方法引起的,该方法正在从willturnintofult内部设置/取消设置KVO值。