문제

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.

도움이 되었습니까?

해결책 2

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

다른 팁

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top