2016-02-06 53 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