2011-05-17 29 views
1

我有一個NSOperation它更新應用程序數據。此操作具有其自己的上下文,並且通過contextDidSave通知將更改傳回到主線程中的上下文。核心數據保存競爭條件錯誤

更新操作刪除對象。這些刪除操作無意中導致崩潰。主線程在更新上下文保存的同時重新加載UITableView時發生崩潰。 tableview的數據源由NSFetchedResultsController支持。

CoreData或UIKit都不輸出任何日誌記錄。崩潰是在訪問managedObject的屬性時發生在tableView:cellForRowAtIndexPath:中的SIG_ABRT。這是成功更新的結果。你可以看到,該表填寫一次,然後背景下保存,這反過來又導致表被重新加載:

tableView:numberOfRowsInSection: rowCount = 29 
tableView:cellForRowAtIndexPath: row: 0 
tableView:cellForRowAtIndexPath: row: 1 
tableView:cellForRowAtIndexPath: row: 2 
tableView:cellForRowAtIndexPath: row: 3 
tableView:cellForRowAtIndexPath: row: 4 
tableView:cellForRowAtIndexPath: row: 5 
tableView:cellForRowAtIndexPath: row: 6 
tableView:cellForRowAtIndexPath: row: 7 
tableView:cellForRowAtIndexPath: row: 8 
tableView:cellForRowAtIndexPath: row: 9 
Will saved update context 
Did saved update context 
Will merge update context 
tableView:numberOfRowsInSection: rowCount = 58 
Did merge update context 
tableView:numberOfRowsInSection: rowCount = 29 
tableView:cellForRowAtIndexPath: row: 0 
tableView:cellForRowAtIndexPath: row: 1 
tableView:cellForRowAtIndexPath: row: 2 
tableView:cellForRowAtIndexPath: row: 3 
tableView:cellForRowAtIndexPath: row: 4 
tableView:cellForRowAtIndexPath: row: 5 
tableView:cellForRowAtIndexPath: row: 6 
tableView:cellForRowAtIndexPath: row: 7 
tableView:cellForRowAtIndexPath: row: 8 
tableView:cellForRowAtIndexPath: row: 9 

這裏是一個發生碰撞時的輸出:

tableView:numberOfRowsInSection: rowCount = 29 
tableView:cellForRowAtIndexPath: row: 0 
tableView:cellForRowAtIndexPath: row: 1 
tableView:cellForRowAtIndexPath: row: 2 
Will saved update context 
tableView:cellForRowAtIndexPath: row: 3 
tableView:cellForRowAtIndexPath: row: 4 
tableView:cellForRowAtIndexPath: row: 5 

stacktrace

我能想到的兩種解決辦法:

  1. 鎖定persitentStoreCoordinator而表格視圖正在刷新。 (這可以通過將UITableView繼承並覆蓋reloadData以提供鎖定和解鎖商店的位置來完成)
  2. 將刪除推遲到稍後的日期,例如,當應用退出時。 (這可以通過添加isStale ATTRIB到實體或創建一個新Trash實體和對象添加到工作要做。)

然而,這兩種解決方案似乎真的哈克。我錯過了什麼嗎?我的第一個嘗試是讓NSFetchedResultsController預取所有對象,但這是不可能的。另一種可能的解決方案是在使用controllerDidChangeContent:時鎖定存儲,但當表重新加載未由fetchedResultsController觸發時問題仍然存在。

+0

@Benedict Cohen崩潰在控制檯和堆棧跟蹤中顯示的是什麼? – 2011-05-17 18:03:14

+0

你確定你做得對嗎? 「這個操作有自己的上下文,並且通過contextDidSave通知將更改傳遞迴主線程的上下文。」這部分看起來特別可笑http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/CoreData/Articles/cdConcurrency.html – TheBlack 2011-05-17 20:56:47

+0

@TheBlack我已經加倍檢查,我99%肯定我'米做對了。我已閱讀並重新閱讀使用通知的其他線程中的跟蹤更改以及mergeChangesFromContextDidSaveNotification:的文檔。 http://developer.apple.com/library/ios/documentation/cocoa/conceptual/CoreData/Articles/cdConcurrency.html#//apple_ref/doc/uid/TP40003385-SW5 – 2011-05-17 21:28:09

回答

0

正如其他人所說,堆棧跟蹤至關重要。沒有,我們只能猜測解決方案。