2016-02-06 51 views
1

我正在處理的情況是,如果存在將被刪除的對象會通過級聯刪除關係導致指數級刪除的情況。通過這種方式,刪除這些對象中的20個可能會導致〜3,000個對象最終被刪除。如果使用主要上下文執行,這會導致非常緩慢的保存。在覈心數據中處理大量刪除/插入

爲了解決這個問題,我創建一個使用相同的持久性存儲爲主要背景下,「工人」背景下,更改那裏,然後保存工人背景和合並與主背景下這些變化:

NSManagedObjectContext *workerContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 

workerContext.persistentStoreCoordinator = mainContext.persistentStoreCoordinator; 

[notificationCenter addObserver:self selector:@selector(workerContextDidSave:) name:NSManagedObjectContextDidSaveNotification object:workerContext]; 

// Here I do a 'superficial' deletion on the main context, so the UI updates, 
// but do the actual deletion on the worker context. Then I save the worker context: 

[workerContext save:nil]; 

// Which fires spawnedWorkerContextDidSave:, where I merge changes to the main context: 

[mainContext performBlockAndWait:^{ 
    [mainContext mergeChangesFromContextDidSaveNotification:notification]; 
}]; 

我的問題是:處理這些大批量刪除批次的最常用方法是什麼?我的方法有什麼缺陷嗎?另外,合併會在主線程上造成一些小的延遲,但是當我執行刪除操作並保存在主線程中時,它並沒有接近它的位置。

+0

嘗試在主線程中不使用GCD。 –

+0

@SunilSingh這就是我在這裏所做的。工作者上下文使用它自己的線程。 – mattsven

回答

1

通過第二個上下文刪除數據的方法很好。

如果您首先預取數據,您可能會發現它的運行速度更快:只需對將在後臺上下文中刪除的對象執行獲取請求,並將關係設置爲預取。這會在刪除之前將數據拖入行緩存(內存),這可以節省磁盤訪問次數。

如果您發現延遲合併主線程上的更改是一個問題,您可以考慮重新設置主上下文。缺點是您的應用必須重新提取所有數據。例如,您可以發出通知來警告應用程序的不同部分,即重置將會發生,並且b)已經發生。

最後,核心數據中現在有API用於在後臺執行大量刪除操作,而無需將數據提取到內存中。主要缺點是你必須小心自己合併已刪除的對象,因爲上下文不知道它們已被刪除。

+0

謝謝德魯!我會嘗試一下你的建議,特別是預取。 – mattsven