willTurnIntoFault вызывается более одного раза, что приводит к сбою - PullRequest
1 голос
/ 23 ноября 2010

В подклассе NSManagedObject моя переопределенная реализация willTurnIntoFault вызывается дважды при отмене некоторого кода, который первоначально создал рассматриваемый объект.Это приводит к сбою при попытке двойной отмены регистрации для KVO по ключевому пути.

В документах Apple говорится, что это подходящее место для отмены регистрации в KVO.

Немного контекста- операция отмены включает удаление соответствующего представления модели из ее суперпредставления.Представление сохраняет свою модель.

Так что мой вопрос: , какие ошибки программиста могут привести к тому, что willTurnIntoFault будет вызван дважды в подклассе NSManagedObject?

Примечание: Ранее я переопределял dealloc в этом классе, но с тех пор понял, что это не рекомендуется для подклассов NSManagedObject.С тех пор я переместил этот код в -didTurnIntoFault.В настоящее время я не отменяю никаких других методов, которые, согласно документам Apple, не следует отменять.

Ответы [ 2 ]

3 голосов
/ 15 августа 2011

Ради потомков: у меня была такая же проблема. В моем случае у меня был объект A с отношением (к одному) к объекту B . Когда A было удалено, обратное отношение B к A было установлено на null. Это вызвало вызов метода B observeValueOfKeyPath:ofObject:change:context (где keypath было отношение B к A ). К сожалению, этот метод проверил свойство A , что привело к отмене сбоя A (обратите внимание, что в этой ситуации awakeFromFetch не вызывается - я предполагаю, потому что объект никогда на самом деле попал в состояние вины). Следовательно, я мог бы получить второй вызов willTurnIntoFault позже, и объект попытался бы снова отменить регистрацию для KVO, что привело бы к сбою - как в OP.

Для меня решение состояло в том, чтобы изменить правило удаления для A на каскадное, чтобы объект B удалялся при удалении объекта A AND , чтобы отменить регистрацию для KVO в prepareForDeletion. Это важно, потому что удаление A все равно приведет к тому, что обратное отношение B будет установлено равным нулю, прежде чем B будет фактически удалено.

Обратите внимание, что prepareForDeletion вызывается до , но не вместо из willTurnIntoFault. Следовательно, если вы отменили регистрацию для KVO в обоих случаях, вам нужно сохранить некоторое состояние, чтобы убедиться, что вы еще не зарегистрированы.

0 голосов
/ 01 декабря 2010

Кажется, проблема была вызвана пользовательским методом установки, который устанавливал / сбрасывал значения KVO из willTurnIntoFault.

...