一个 NSPersistentStoreCoordinator 下的多个 NSManagedObjectContexts 抛出“statement is still active”异常

Posted

技术标签:

【中文标题】一个 NSPersistentStoreCoordinator 下的多个 NSManagedObjectContexts 抛出“statement is still active”异常【英文标题】:Multiple NSManagedObjectContexts under one NSPersistentStoreCoordinator throws 'statement is still active' exception 【发布时间】:2015-09-16 07:46:16 【问题描述】:

我正在将我的 CoreData 设置更改为在 1 个 NSPersistentStoreCoordinator 下有 2 个 NSManagedObjectContexts。

    Root ContextNSManagedObjectContextNSPrivateQueueConcurrencyType 实例化并设置为NSMergeByPropertyStoreTrumpMergePolicy 主上下文NSManagedObjectContext 实例化的 NSMainQueueConcurrencyType 也设置为 NSMergeByPropertyStoreTrumpMergePolicy

它们都没有通过“父子”关系连接,但是它们被分配了相同的NSPersistentStoreCoordinator 对象。 主上下文正在监听根上下文NSManagedObjectContextDidSaveNotification通知并在performBlock:内部进行必要的合并

偶尔,当NSFetchedResultsController 的实例与主上下文 挂钩时,我得到了performFetch

由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“语句仍处于活动状态”

我想知道我在这里要做的事情是不应该做还是Core Data的限制。

谢谢

【问题讨论】:

是什么导致决定不通过父子关系连接上下文? 我觉得如果我让 Main Context 成为 Root Context(我们目前拥有的模型)的子级,并且我们有一个“ Import Context" 作为 Main Context 的子级,它会减慢 UI,因为每个更改都必须经过 Main Context 的队列 只是为了确认一下,你打电话给mergeChangesFromContextDidSaveNotification:? @MatthewGillingham 是的 【参考方案1】:

Florian Kugler 写了一篇很好的文章:The Concurrent Core Data Stack

这个想法是将您的数据导入私有队列上下文(Import Context),它是Main Context的子级。

这个Main Context在主队列上(我喜欢叫它UI队列),所以你可以在主线程(UI线程)中使用它里面的对象,而不必从主线程的私有线程。

最后,主上下文是您的 根上下文 的子上下文,它在自己的私有队列中运行。这样保存将在后台线程中完成,不会阻塞您的 UI。

由于在此设置中您从不接触 [根上下文],即您从不直接对其进行更改,所有更改都流经主上下文。因此,您将始终在主线程上获得最新数据。无需手动收听更改通知和合并更改。

首先我不会担心性能。 Core Data 已经过高度优化,如果出现性能问题,您可以减少单个导入工作程序保存的数据量。

【讨论】:

好点,谢谢@Mark。事实上,这是我目前的模型,但由于所有更改(通过链保存时)都需要通过 UI 队列,我觉得一些 UI(即动画)正在生涩。所以我想尝试不同的方法来改进它。毕竟可能不是最好的方法。 您无法真正绕过它,因为您希望您的 UI 无论如何都是最新的。所以你必须让 Core Data 履行职责。如果您遇到缓慢的问题,请使用仪器来检测性能问题并一次解决一个问题。始终保持较小的进口工人负载,并以大约 500-5000 件的批量保存(取决于复杂性)。 我认为这取决于用例,但在我们的应用程序中,我们不介意牺牲一些延迟来获取 UI 中呈现的数据,然后不得不体验 UI 抖动。我会玩一玩,但非常感谢您的建议。

以上是关于一个 NSPersistentStoreCoordinator 下的多个 NSManagedObjectContexts 抛出“statement is still active”异常的主要内容,如果未能解决你的问题,请参考以下文章

我可以在 jQuery 中创建一个“if”语句来检查一个集合中的一个类和另一个集合中的一个类吗?

当最后一个可以小于第一个时,在数组中从第一个移动到最后一个

从另一个片段打开一个片段始终保留前一个片段标题

LaTex里怎么打一个方框里一个加号和一个方框里一个等号?

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点)。

如何证明一个集合是另一个集合的子集