[英]Concurrency with core data
我正在使用多線程來獲取數據,解析它,創建對象並存儲它們。 在完成所有這些之后,我希望顯示該窗口。 但是現在我有兩個問題:
我認為僵局是因為我同時在多個線程中更新了ManagedObjectContext。
所以我用ConcurrencyType更改了managedObjectContext:
__managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
並為並發隊列創建了一個importContext並分配了parentContext:
NSManagedObjectContext *importContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; importContext.parentContext = self.managedObjectContext;
並將我的操作放入importContext的performBlock中:
[importContext performBlock:^{ dispatch_async(backgroundQueue, ^{ [myObject methodAWithContext:importContext]; }); dispatch_async(backgroundQueue, ^{ [myObject methodBWithContext:importContext]; }); dispatch_async(backgroundQueue, ^{ [myObject methodCWithContext:importContext]; }); dispatch_barrier_async(backgroundQueueM, ^{ // create barrier to wait for the first 3 threads to be completed. dispatch_async(dispatch_get_main_queue(), ^{ // Save the data from the importContext tot the main context on the main queue NSError *importError = nil; [importContext save:&importError]; [importContext.parentContext performBlock:^{ NSError *parentError = nil; [importContext.parentContext save:&parentError]; }]; [self.window makeKeyAndVisible]; }); }); }];
方法1:在每種方法中,我選擇一個對象子集,將其刪除,然后創建新對象並保存。 (我認為刪除比進行提取並檢查要創建的每個對象是否存在都快)。 因此:在方法AI中,選擇所有AObject,將其刪除並創建新的AObject。 在“方法BI”中,選擇所有BObject,將其刪除並創建新的BObject。 在方法CI中,選擇所有CObject,將其刪除並創建新的CObject。
但隨后出現錯誤“ NSManagedObjectContext無法刪除其他上下文中的對象”。
所以方法2:我刪除了刪除。 但是現在我遇到了各種不同的錯誤.....並且屏障不等待其他線程被執行。
Q1:我在做什么錯?
Q2:如何獲得等待3個線程完成的障礙
問題3:如何刪除/清除各個線程上的對象?
(我已經閱讀了Apple發行說明和文檔,但是找不到有關多線程和ManagedContext組合的清晰說明。)
您不能在performBlock
調用dispatch_async
。 NSPrivateQueueConcurrencyType
類型的托管對象上下文具有自己的調度隊列,用於執行操作。
您嘗試通過將它們移到不同的調度隊列來並行執行多個操作,但這是不可能的。
如果確實必須並行執行多個操作,則必須為每個操作創建一個私有並發類型MOC。
添加:
等待所有操作完成的方法有幾種:
performBlock:
的末尾增加一個計數器performBlock:
並檢查其值是否為(在您的示例中)3。 dispatch_semaphore_create
與初始值為零每一個操作),等待所有的信號量( dispatch_semaphore_wait
),並在每年年底的信號旗語performBlock
。 但是:在我重新閱讀您的問題時,我發現您嘗試延遲
[self.window makeKeyAndVisible];
直到所有核心數據提取操作完成。 這不是一個好的設計,因為在完成數據導入之前,用戶將看不到任何東西。
更好的設計是立即顯示初始視圖,並在后台操作獲取數據后更新該視圖。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.