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