willTurnIntoFault 被多次调用,导致崩溃

发布于 2024-10-04 02:34:49 字数 441 浏览 6 评论 0原文

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

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

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

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

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

In a subclass of NSManagedObject my overridden implementation of willTurnIntoFault is being called twice when undoing some code which originally created the object in question. This results in a crash when attempting to double-unregister for KVO on a key path.

The Apple documents say this is the right place to un-register for KVO.

A bit of context - the undo operation involves removing the corresponding view of the model from it's superview. The view retains it's model.

So my question is: what kind of programmer errors can result in willTurnIntoFault being called twice in a subclass of NSManagedObject?

Note: Previously I was overriding dealloc in this class but have since realised this is not recommended for subclasses of NSManagedObject. I've since moved this code into -didTurnIntoFault. I'm not currently overriding any other methods which the Apple docs say you should not override.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

吾性傲以野 2024-10-11 02:34:49

为了后代:我也遇到了同样的问题。就我而言,我有一个对象 A 与对象 B 具有(一对一)关系。当A被删除时,BA的逆关系被设置为null。这导致BobserveValueOfKeyPath:ofObject:change:context方法被调用(其中keypathB' s 与A的关系)。不幸的是,这个方法检查了 A 的属性,导致 A 的错误被取消(请注意,在这种情况下 awakeFromFetch 不会被调用 - -我推测是因为该对象实际上从未进入故障状态)。因此,我可能会在稍后再次调用 willTurnIntoFault,并且该对象会再次尝试注销 KVO,从而导致崩溃 - 就像在 OP 中一样。

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

请注意,prepareForDeletionwillTurnIntoFault 之前调用,而不是代替。因此,如果您在两者中取消注册 KVO,则需要维护某种状态以确保您尚未取消注册。

For posterity's sake: I had the same problem. In my case I had an object A with a (to-one) relation to an object B. When A got deleted B's inverse relation to A was set to null. This caused B's observeValueOfKeyPath:ofObject:change:context method to be invoked (where keypath was B's relation to A). Unfortunately this method checked a property of A, causing the faulting of A to be cancelled (note that in this situation awakeFromFetch does not get called--I presume because the object never actually did get to fault state). Hence I might might get a second call to willTurnIntoFault later and the object would try to unregister for KVO again, resulting in a crash--just like in the OP.

For me the solution was to change the delete rule for A to cascade, so that the B object got deleted when the A object got deleted AND to unregister for KVO in prepareForDeletion. This is important because the deletion of A will still cause B's inverse relation to be set to nil before B is actually deleted.

Note that prepareForDeletion gets called before but not instead of willTurnIntoFault. Hence, if you unregister for KVO in both, you need to maintain some state to make sure you have not already unregistered.

·深蓝 2024-10-11 02:34:49

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

Seems the issue was caused by a custom setter method which was setting/unsetting KVO values from within willTurnIntoFault.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文