2010-06-28 32 views
0

我在開發具有核心數據的iPhone應用程序時遇到了崩潰問題。核心數據後臺同步衝突問題

該應用程序與後臺線程上的web服務同步數據。

當應用第一次啓動時,核心數據數據庫中的現有數據將在UITableView中顯示給用戶,而後臺線程脫離抓取Web服務API中的最新數據。讓我們調用核心數據模型用戶和項目,僅用於有許多項目的用戶進行討論。這些項目是在UITableView中顯示的內容。

當API結果返回時,將從核心數據中刪除用戶現有項目記錄,並將新的一組項目記錄插入到核心數據中。一旦所有項目被解析,一條消息被髮送回主線程以合併核心數據更改並從CD重新獲取數據。

但是,我一直崩潰在我的配置表單元格例程,我敢肯定它因爲超出範圍對象。意思是,主線程試圖顯示來自核心數據的對象,而後臺線程正在從核心數據中刪除那些相同的對象,並用新數據替換它們。

處理這類衝突的最佳方法是什麼?我必須放入某種機制才能啓動後臺線程更新,直到主視圖加載/顯示其所有數據爲止?如果是這樣,我該如何做到這一點?我是否仍然可以保持相同的方法,只是更好地刪除顯示的項目?

+0

有沒有什麼辦法來鎖定單個持久性存儲協調器,而我正在刪除記錄?或者我應該使用獨立的持久性商店協調員?我不確定,只是在這裏大聲說出來,因爲這是我第一次在應用程序中使用Core Data。 – cpjolicoeur 2010-06-28 15:01:22

+0

爲什麼項目實體被刪除而不是與web服務調用中的更新狀態合併? – falconcreek 2010-06-28 15:16:16

+0

他們正在被刪除,因爲我認爲我更容易刪除並重新插入更新的數據,而不是嘗試管理與項目的狀態差異。如果我試圖更新,我需要跟蹤哪些屬性發生了變化,然後更新這些屬性,或者只是從API服務器完全重置項目。 我最初的想法是,只做一個批量刪除/替換,而不是通過API中的對象進行解析,對Core Data執行單一查找,然後執行另一個更新操作 – cpjolicoeur 2010-06-28 15:23:26

回答

1

參考TopSongs項目SongsViewController實施 具體viewDidLoadhandleSaveNotification

- (void)handleSaveNotification:(NSNotification *)aNotification { 
[managedObjectContext mergeChangesFromContextDidSaveNotification:aNotification]; 
[self fetch]; 
} 

你的viewController的handleSaveNotification:不會被調用,因爲你註冊了來自商務部的通知,它擁有,並不是所有的MOC的。它適用於TopSongs示例,因爲應用程序委託和viewController的MOC是同一個對象。 (appDelegate將moc傳遞給songsViewController)。

替換:

// ViewController.m viewDidLoad 
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleSaveNotification:) name:NSManagedObjectContextDidSaveNotification object:self.managedObjectContext]; 

有了:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleSaveNotification:) name:NSManagedObjectContextDidSaveNotification object:nil]; 

替換:

// ViewController.m viewDidUnload 
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:self.managedObjectContext]; 

有了:

[[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:nil]; 
+0

的通知,這實際上正是我正在做的。我模擬了Apple的TopSongs示例項目的大部分後臺更新代碼。 – cpjolicoeur 2010-06-28 16:39:53

+0

可以在兩個地方註冊相同的通知,對嗎?我在視圖控制器和我的應用程序委託中註冊了此通知,就像TopSongs項目中的示例 如果我在兩個回調中都放置了日誌消息,我只能看到來自應用程序委託中的日誌消息,而不是在我看來控制器 – cpjolicoeur 2010-06-28 16:43:58

+0

是的。通知之美。 – falconcreek 2010-06-28 16:46:18

0

這些核心數據操作是否如此昂貴以至於無法從主線程執行此操作?只需在另一個線程上執行webservice部分即可。否則,它可能會變得更加困難 - 也許會放置一些控制器類來緩存相關數據或同步對Core Data的訪問。

+2

昂貴的部分只是從API服務器獲取數據的潛在延遲。不想在上傳時阻止UI,或者在這種情況下從API服務器下載更新的數據。 核心數據操作本身並不重要,沒有。我想我可以重構我的工作,並在主線程上執行實際的CD刪除/插入方法,如果這是最佳解決方案 – cpjolicoeur 2010-06-28 14:59:48

+0

是否有任何本機緩存解決方案或我必須推出自己的緩存控制器? – cpjolicoeur 2010-06-28 15:00:39

+1

'NSFetchedResultsController'用於以安全的方式將Core Data連接到'UITableView',它也處理數據的更改。 – 2010-06-28 15:04:51

0

您如何訪問表中的數據?如果您使用的是NSFetchedResultsController,它應該以安全的方式自動更新單元格。

在原始問題的範圍內:
除非您的數據保存在其他位置,否則在滾動表格時重繪單元可訪問數據。你可以可以複製你用來填充單元格的所有數據,但這會增加你的內存使用量。

+0

我正在使用NSFetchedResultsController在UITableView中顯示數據。我以爲frc爲你處理了處理,但我的猜測是它試圖在後臺線程中刪除它的同時顯示數據,並且由於單獨的managedObjectContexts並不知道它被刪除了,並且它沒有被告知否則合併新的更改 – cpjolicoeur 2010-06-28 15:07:45

0

審查覈心數據多線程的提示檢查NSFetchedResultsControllerDelegate方法controllerWillChangeContent:controllerDidChangeContent:

您有責任通知表格,您將使用beginUpdatesendUpdates消息更改表格。當獲取的結果控制器要修改返回的數據時,表需要凍結自身更新,直到控制器完成。否則,表格試圖表示一個不斷移動的數據列表。

+0

我覺得有點困惑。你提到的那些方法是FRC委託協議的一部分,對嗎?它們不是我目前手動調用的。我怎麼會從我的後臺線程手動調用它們?或者,這不是你想要做的? – cpjolicoeur 2010-06-28 16:03:05

+0

你實現了委託方法。這些消息被髮送到您的FRC實例的委託對象。這通常是管理tableView的相同控制器對象。 – falconcreek 2010-06-28 16:22:06

+0

沒錯。我確實在視圖控制器中實現了那些保存管理UITableView的FRC的委託方法。我不遵循的是我的後臺線程控制器正在執行後臺線程的刪除和更新?這是如何影響和/或調用主線程上的視圖控制器上的FRC委託方法以防止刪除崩潰問題? – cpjolicoeur 2010-06-28 16:26:32

0

你解決了這個問題嗎?

檢查您 一)未使用高速緩存 - 即你的電話,當你最初創建FRC不使用緩存:

NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:nil] 

(見cacheName:無)

B)你在FRC中使用謂詞?現在我遇到了各種各樣的問題,試圖做與代碼一樣的事情。

+0

不,我還沒有找到解決方案,是的,我實際上正在使用緩存。我會嘗試它沒有緩存,看看它是否修復我的問題。爲什麼緩存會導致描述的錯誤? 另外,我在我的FRC中使用謂詞,是的。 – cpjolicoeur 2010-09-27 13:16:36