2010-09-09 58 views
6

我想我理解錯誤消息:CoreData無法履行錯誤,但我不知道該如何處理它。當HTTP服務更新對象時,CoreData無法完成故障

我們有一個應用程序,我們使用Core Data來保存從JSON服務返回的數據。今天我正在做以下事情。

  1. 從持久性存儲中獲取本地對象,並返回到UI
  2. 詢問服務器如果對象被更新 - 當我得到的答案,我更新了核心數據管理對象
  3. 更新UI與更新的對象

問題是;即使我不使用多線程,當HTTP請求刪除我的UI保留的託管對象時,我有時也會收到錯誤。我試圖用returnsObjectsAsFaults將對象提取爲NO。我想我可以訪問所有的管理對象的關係和屬性,即使它被刪除了(只要我的用戶界面保留了它)。

我應該如何解決這個問題?

我想我可以使用單獨的NSManagedObjectContext進行讀取和寫入。我做了這個測試:

MyAuthorMO *authorUpdate = [[MyAuthorMO alloc] init]; // I have made this init insert the object into the updateContext 
authorUpdate.firstname = @"Hans"; 
authorUpdate.lastname = @"Wittenberg"; 
authorUpdate.email = @"[email protected]"; 

NSManagedObjectContext *updateContext = [[MyCoreManager getInstance] managedObjectContext]; 

NSError *error = nil; 
[updateContext save:&error]; 

NSManagedObjectContext *readContext = [[MyCoreManager getInstance] readOnlyContext]; 

NSFetchRequest *fetchRequest = [managedObjectModel fetchRequestFromTemplateWithName:@"authorByEmail" substitutionVariables:[NSDictionary dictionaryWithObject:@"[email protected]" forKey:@"EMAIL"]]; 
[fetchRequest setReturnsObjectsAsFaults:NO]; 

NSArray *authors = [readContext executeFetchRequest:fetchRequest error:&error]; 

MyAuthorMO * readAuthor = [authors objectAtIndex:0]; 

// Delete the author with update context: 
[updateContext deleteObject:authorUpdate]; 
[updateContext save:&error]; 

NSLog(@"Author: %@ %@, (%@)", readAuthor.firstname, readAuthor.lastname, readAuthor.email); 

只要我使用readContext進行讀取,日誌輸出就好了。如果我使用updateContext進行提取,我會得到一個異常。這看起來很有前途,但恐怕我會在後期遇到問題。遲早我可能會嘗試訪問一個不完全提取的屬性(一個錯誤)。我如何實現我正在尋找的行爲?

+0

尼克,你可能是對的。我已閱讀我以前的帖子並接受了最佳解決方案。謝謝你的評論。 – Andi 2010-09-10 06:11:52

回答

14

您不應該保留上下文已發佈的託管對象。讓上下文爲你做。

問題是管理對象可以作爲故障或實際對象存在。當您保留一個,您可以保留不包含數據的故障。即使您確實保留了實際的對象,但該對象在與上下文分離之後可能無法正常運行。

爲了處理您的情況,您需要UI的上下文,然後需要服務器的上下文。在任何上下文進行更改後,您應合併上下文以確保兩者都相對於商店正確更新。

您的UI應配置爲反映數據模型的狀態,您不應該讓數據模型的某些部分依賴於UI的狀態。

+1

我同意你的意見,但有一些跟進問題。我沒有保留MO,但是如果我在某個地方使用它,可能會在我不知道的情況下保留它。添加MO到NSArray或NSDictionary可以嗎?如果是這樣,那麼它將被保留... 我是否需要合併上下文,或者我可以等待下一次從「read」-context「中獲取?我擔心如果我的數據被損壞合併兩個上下文,其中我當前正在渲染的對象被刪除(使用「write」-context)。 – Andi 2010-09-13 18:56:41

+1

我還不清楚。我的意思是你不應該試圖保留一個上下文已經處理的託管對象。這會變得混亂。您應該合併上下文,但您需要在模型更新時凍結界面。看看NSFetchedResultsController如何在數據顯示在表中時更新數據來處理這個確切的問題。凍結用戶界面通常完全不被用戶察覺。如果您的數據在用戶使用時可能會被刪除,您需要重新考慮您的設計。用戶應該控制這種刪除。 – TechZen 2010-09-14 11:55:55

0

我在我的數據庫中有同樣的問題,因爲我指的是不存在的對象(因爲我用其他關係對象刪除它)。我的解決方案是在我的關係中設置「無動作」。