处理核心数据中的大量删除/插入

时间:2016-02-06 03:14:19

标签: ios multithreading macos core-data

我正在处理一个场景,其中有些对象如果要删除,会通过级联删除关系导致指数级的删除。这样,删除这些对象中的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];
}];

我的问题是:处理这些大型删除批次的最常用方法是什么?我上面的方法有什么陷阱吗?另外,合并会导致主线程出现一些小的延迟,但是当我进行删除并保存在主线程上时,没有任何附近的内容。

1 个答案:

答案 0 :(得分:1)

通过第二个上下文删除数据的方法很好。

如果您首先预取数据,您可能会发现它的工作速度更快:只需对您将在后台上下文中删除的对象执行获取请求,并将关系设置为预取。这将在您删除之前将数据拉入行缓存(内存),这可以节省到磁盘的行程。

如果您发现合并主线程更改的延迟是个问题,您可以考虑重置主要上下文。缺点是你的应用程序必须重新获取其所有数据。例如,您可以触发通知以警告应用程序的不同部分,重置是a)将要发生,并且b)已经发生。

最后,Core Data中现在有API用于在后台执行大型删除操作而不将数据拉入内存。主要的缺点是你必须小心自己合并已删除的对象,因为上下文不会知道它们已被删除。