将NSPrivateQueueConcurrencyType子上下文与NSPrivateQueueConcurrencyType父上下文

时间:2016-04-29 20:15:41

标签: ios multithreading core-data concurrency

我在使用子上下文作为NSPrivateQueueConcurrencyType的便笺簿时遇到了问题。

我的核心数据堆栈如下所示: core data stack

视图控制器使用主上下文。 Worker Context用于从API导入数据。我使用mergeChangesFromContextDidSaveNotification来合并Main和Worker上下文之间的更改。如果我将工人孩子的背景置于等式之外,那么事情似乎正常。

但是,我想在导入对象时使用worker子上下文作为便笺簿。有些数据需要构建嵌套对象,如果构建过程中某处出现错误,我只想抛弃那个上下文。如果构建成功,我希望能够保存工作者子上下文,让它将更改推送到工作者上下文,然后可以将更改保存并合并到主上下文中。

但是,当我尝试在Worker子上下文中执行获取请求来执行查找或创建时,即使它是在Worker Child Context的performBlock内完成的,我也得到了多线程断言。

我不确定哪些代码段会对回答这个问题有所帮助,但我主要担心的是我的整体方法是不会起作用的。将私有队列上下文作为另一个上下文的子项是一个坏主意吗?

修改

我遇到的崩溃是当工作者子上下文尝试执行获取请求以执行查找或创建操作时。它不使用谓词中的任何托管对象,它包含在performBlockAndWait中。我得到的解释是' NSInternalInconsistencyException',原因:'语句仍处于活动状态' 崩溃是间歇性的,但到目前为止似乎是只有当我有嵌套的工作者子上下文时才会发生。 (即我的图中的工作者子上下文将具有其自己创建对象的子上下文)

导致崩溃的获取请求始终用于查找或创建操作,因此它尝试获取具有与要导入的对象的标识符匹配的唯一标识符属性的任何对象。所以谓词总是像"identifier in ["1234", "abc", "etc" ]

正如我在评论中提到的,我最初使用的是PSC - >私人背景 - >主要背景 - >私人工作者背景设置。我在导入数据时工作者上下文获取和保存时遇到UI冻结,所以我试图重构到这个堆栈以释放UI。

1 个答案:

答案 0 :(得分:0)

显示您的提取及其谓词将有助于确定发生了什么。听起来你正在跨越线程边界访问NSManagedObject,也许在你的谓词中使用一个?

顺便说一句,如果您将工作人员移到主队列下,则无需处理消费通知。其他所有内容都完全相同,但您可以处理更少的代码,减少线程问题的风险。

  

我最初在我的主要队列下有工人。 PSC - >私人队列 - >主队列 - >私营工人。我正在重构我正在询问的设置,因为我遇到了UI被阻止而工作者上下文正在获取/保存以查找或创建导入。除了重构核心数据堆栈之外,还有另一种优化性能的方法吗?

您是否运行过仪器以确定该块来自儿童MOC?在每种情况下,我都听说过这个问题,我发现它是其他东西(通常是UI相关的),这是问题的实际来源。除非您针对错误谓词获取 THOUSANDS 对象,否则您不应该感觉到获取的内容。即使这样,谓词也会被优化以解决问题。

对于保存,您可以A)增加保存频率,或者B)设置私有MOC作为磁盘写入器。我更喜欢B,所以保证所有保存都是异步的。