2009-08-09 50 views
11

我有一個錯誤,我正在努力追查。我相信發生的事情是我從基礎數據庫中刪除了一個對象,而另一個受管對象上下文(在另一個線程中)出現了錯誤,並在嘗試執行錯誤時獲取'NSObjectInaccessibleException'。調試NSObjectInaccessibleException - ID爲0x123456789的NSManagedObject已失效

這種情況是我有一個視圖通過一個上下文同時在後臺訪問數據,另一個威脅是清除存儲過時的記錄。後臺線程只能清除視圖不需要的對象 - 顯然不是這種情況,但我無法準確跟蹤發生的情況。當我看到缺陷時,已經太遲了,這是一個相對罕見的缺陷,主要只發生在現場。

因此我的問題:在調試CoreData時是否有任何技巧缺失 - 我可以從另一個上下文中跟蹤對象的生命週期嗎?即當我刪除我的對象有一個簡單的方法來查看是否有任何其他上下文有一個對同一個對象的引用?使用它,我可以構建一些測試代碼來檢查我的邏輯並找出錯誤。

+0

吉姆,你爲什麼要拋棄我的iPhone標籤我改變簡單地固定?我正在研究iPhone,所以我沒有CoreData綁定。 – 2009-08-11 13:19:19

+0

羅傑 - 我把iPhone標籤放回去了。但這實際上是一個通用的核心數據問題,可能發生在桌面或移動平臺上。 – 2009-08-11 15:23:01

+0

所以我診斷出這是一個iPhone問題,雖然可能發生在任何地方。 – 2009-10-31 08:12:44

回答

1

解決方案是清理和this mapkit bug的組合。在我釋放了我的NSManagedObjectContext之後,地圖視圖保存在它的委託中。 Mapkit向委託人詢問註解的座標,我的委託對象試圖查詢處於已發佈上下文中的對象(類似於Jason的問題)。

解決方法與Jake的博客文章中描述的一樣 - 在完成地圖視圖時將代表設置爲零。

+0

鏈接已損壞。你有新的,還是可以解釋? – bearMountain 2012-10-02 22:27:21

+0

我以爲我做到了。問題在於有些類對它們的委託持有一個弱引用,並在它被處理後向它發送消息。如果你看到這個問題,請確保你是代理的任何類中的無委託(或數據源)引用。 – 2012-10-03 10:25:26

+0

感謝您的澄清。 – bearMountain 2012-10-15 18:06:42

1

當它試圖在已從持久存儲中刪除的對象中發生故障時,第二個上下文是做什麼的?

這聽起來像一個錯誤,它可能包含2個部分:您沒有合併來自對等上下文的更改,並且您有一個邏輯錯誤導致您使用線程B中已刪除的線程中的對象

通常情況下,您需要使用-[NSManagedObjectContext mergeChangesFromContextDidSaveNotification:]合併來自對等上下文的更改。

+0

我認爲這裏有兩個錯誤,我同意它們是什麼:-(我需要的是一種跟蹤它們的方法 – 2009-08-11 13:17:43

+0

您是否正在合併來自對等上下文的更改?出於調試目的,您可以在上下文時記錄已刪除的對象如果你知道所有其他現存的上下文是什麼,你也可以檢查這些上下文中註冊的對象,但是你必須以線程安全的方式來完成這個工作 – 2009-08-11 15:25:06

+1

你是對的,我決定我需要修復整個線程狀況來解決這個問題,這不是微不足道的,但可能對我的健康有好處 – 2009-08-12 10:27:50

7

我之前遇到過這個錯誤,罪魁禍首是我正在清理(完成發佈)我的上下文,然後嘗試訪問由該上下文管理的對象(以前)。

在我的情況下,上下文是一個「臨時」上下文,當視圖關閉時會消失。然而,我有一個後臺工作,該視圖產生了想要更新對象的想法。

我最終爲[managedObject isFault]爲true時返回nil的託管對象創建了一個存取器。然後在我的代碼中,我正在檢查訪問器選擇器的值,以確保我有一個有效的對象來處理(例如,當我的後臺作業最終完成其工作時)。

我對Core Data很新,所以可能有更好/更聰明的方法來做到這一點,但我認爲它解決了我的問題。

+0

Jason,謝謝你的回覆,我注意到了,最近我修復了錯誤,它是清理和MapKit組合的映射視圖保持它們的委託過長。在你的情況下,你可能不應該從後臺線程訪問相同的NSMAnagedObject上下文 - CoreData不是線程安全的,而是你應該將一個NSManagedObjectReference傳遞給你的後臺任務。 – 2009-10-31 08:15:04

+0

是的,你絕對是對的。就我而言,在實際編輯對象之前,我已經回到了主線程(創建所有上下文)的地方,但是當它的上下文已經過去時,它仍然沒有好處。 – Jason 2009-11-02 16:16:59

+1

你說的是什麼「NSManagedObjectReference」? 不存在,根據文檔... – Adam 2010-07-10 02:25:16

2

我剛剛也面臨這個問題。我做了一些重構,以遵循Apple的「查找或創建」模式以批量導入數據。我建立了一個專用於導入的新上下文,通過設置undomanager爲零。 所以:

// create a new special context for the bulk import of data 
NSManagedObjectContext *importContext = [[NSManagedObjectContext alloc] init]; 
[importContext setPersistentStoreCoordinator:_persistentStoreCoordinator]; 

// avoid tracking for undo/redo operations 
[importContext setUndoManager:nil]; 

然後我創建了一個fetchRequest檢索存儲在數據庫中的對象的ID和進口環內我測試對象的ID查找只要含有的ID檢索到的數組中的...問題是,在給定的時間間隔中,我保存了importContext並重置它。因爲我錯誤地引用了importContext而不是defaultContext,所以我得到了這個錯誤。

NSArray *storedObjects = [importContext executeFetchRequest:checkRequest error:&fetchError]; 

有:

NSArray *storedObjects = [defaultContext executeFetchRequest:checkRequest error:&fetchError]; 
+8

只是iOS用戶的一個小旁註。在iOS上,'undoManager'屬性默認爲'nil'。 – stigi 2013-09-25 14:07:34

相關問題