因爲兩天我試圖讓Core Data與多個線程一起工作。我嘗試使用標準線程限制方法與NSOperations,合併通知,使用objectWithId,每個線程的上下文字典,仍然我得到奇怪的死鎖,不一致性異常和一堆其他討厭的東西。這讓我瘋狂......另外,我無法找到關於如何在兩個線程中管理上下文的單個示例或解釋,當兩個線程都可以對共享持久存儲進行更改時...使用併發類型保存上下文時發生死鎖NSPrivateQueueConcurrencyType
我試圖使用新的iOS 5方法,這應該是更容易,但我仍然得到錯誤。第一個問題是保存上下文時發生死鎖。我刪除了所有不必要的代碼並執行時該代碼足夠快(通過快速敲擊按鈕)STIL得到死鎖:
NSManagedObjectContext *context = [StoreDataRetriever sharedRetriever].managedObjectContext;
for (int i = 0; i < 5; i++) {
NSError *error = nil;
NSLog(@"Main thread: %@, is main? %d", [NSThread currentThread], [NSThread isMainThread]);
BOOL saveOK = [context save:&error];
if (!saveOK) {
NSLog(@"ERROR!!! SAVING CONTEXT IN MAIN");
}
[context performBlock:^{
NSLog(@"Block thread: %@", [NSThread currentThread]);
NSError *error = nil;
BOOL savedOK = NO;
savedOK = [context save:&error];
if (!savedOK) {
NSLog(@"ERROR!!! SAVING CONTEXT IN BLOCK");
}
}];
}
有沒有其他對數據庫的更改,什麼都沒有,只有環境保存。這段代碼有什麼問題?它應該是什麼樣子?
注意:[StoreDataRetriever sharedRetriever] .managedObjectContext是在appDelegate中使用initWithConcurrencyType:NSPrivateQueueConcurrencyType創建的。
所以它並不能幫助那麼多在我的現實世界中的問題:我需要做的耗時的計算在NSManagedbjects的背景中,同時保持UI響應並在主線程上執行一些操作(創建新的託管對象,更改數量等以響應用戶點擊)。我仍然必須使用禁閉或可能創建子上下文?呃... – 2012-07-23 07:57:27
孩子們比較便宜。如果你的計算量很大,那麼兒童背景的成本幾乎沒有。所以是的,這是一個很好的方法,您可以使用performBlock爲您計劃爲特定的子上下文計算特定的子上下文,並將修改保存在最後或者有意義時。這裏是關於那個話題的文章:http://www.cocoanetics.com/2012/07/multi-context-coredata/ – 2012-07-23 08:38:10
不幸的是,我正在修改的現有代碼是使用StoreDataRetriever單例對象模式調用此對象深深地埋在代碼中。在這個階段很難改變它,所以我認爲我會採用舊的禁閉方法。我只需要找出我的代碼有什麼問題... – 2012-07-23 10:27:45