缓慢删除并保存嵌套的NSManagedObjectContext

时间:2012-08-03 18:40:06

标签: ios core-data nsmanagedobjectcontext

在我的应用中,我有一个“主”NSPrivateQueueConcurrencyType上下文,作为视图控制器依赖和传递的NSMainQueueConcurrencyType上下文的父级。我想这样做是为了利用异步保存(这个应用程序使用iCloud与核心数据,并节省了很多工作导出无处不在的日志)。该设置类似于this article

底部提到的Zarra方法

在应用内保存通常如下所示:

[context save:nil];
[context.parentContext performBlock:^{
     [context.parentContext save:nil];
}];

这似乎适用于小编辑/更新,但我对删除许多对象时所看到的内容感到困惑(例如,删除一个包含数百个与之相关的任务对象的项目)。

在那种情况下,保存是异步的,但看起来主线程进入信号量等待情况(如我暂停调试器时所见)并且被有效阻止(我无法在UI中滚动)直到后台私有上下文完成了保存。

实际上,我只是注意到单个对象的滑动删除删除会产生明显的延迟,尽管这种异步保存模式,所以应用程序中的所有删除似乎都很慢。

或者,如果我分配一个新的NSPrivateQueueConcurrencyType上下文,将其持久存储协调器设置为AppDelegate中的主PSC,并执行删除和保存,它仍然会做很多工作但是UI永远不会被阻止(但后来我不得不担心协调上下文,在主要上下文中重新获取)。

任何想法我可能做错了,或者你也见过这种行为?

1 个答案:

答案 0 :(得分:8)

删除可能需要很长时间。他们必须修复所有的关系。在进行大量删除时,您应该做几件事。

首先,为什么你的UI会在后台发生删除时阻止?因为后台线程正忙于执行删除块,并且您的UI正在尝试获取以在删除发生时更新数据。

运行实际工作的线程由FIFO队列管理,因此如果你给它一个大的任务来执行,它将无法完成其他任务,直到长时间运行完成。

您可能正在使用FRC,它正在尝试在对象和关系发生变化时获取更新。

如果您有大量删除,则可能需要更改提取,以便在删除发生时仅查看当前的数据MOC。删除完成后,您可以告诉获取请求返回查询一直到商店本身。

此外,在删除大量内容时,最好在自动释放池内的小块中,在单独的线程中执行。从该后台线程中,一次删除小块,并使用performBlockAndWait执行此操作。这样,您不会使用删除请求加载工作线程的队列,并且您的UI线程可以处理其请求。更快。

或者,您也可以使用GCD的高级功能来拥有一个高优先级和低优先级的队列,用于将工作提供给工作线程。您可以将写入放在低优先级队列上,然后读取高优先级队列。

相关问题