NSConcurrencyType 用于在同一队列上使用独立的 NSManagedObjectContexts

Posted

技术标签:

【中文标题】NSConcurrencyType 用于在同一队列上使用独立的 NSManagedObjectContexts【英文标题】:NSConcurrencyType for using independent NSManagedObjectContexts on the same queue 【发布时间】:2016-11-16 00:52:19 【问题描述】:

在基于 CoreData 的应用程序中,我通过后台 NSOperation 处理导入。因为操作在操作队列上运行,所以我利用旧版NSConfinementConcurrencyTypeNSManagedObjectContext 一起工作。在此导入操作期间,我还访问了辅助数据库的NSManagedObjectContext。由于它在操作队列上运行,所以它也使用线程限制并发类型。这多年来一直很好用,但 NSConfinementConcurrencyType 现在在 ios 9 中已被弃用。

看来我唯一的(非弃用)选项是使用NSPrivateQueueConcurrencyType,在performBlock: 中为主要上下文执行导入,并包装对次要上下文的每次调用或来自次要上下文的NSManagedObjects performBlockAndWait: 中的上下文。此外,我必须非常小心,不要触摸来自错误队列的其他上下文中的对象。

这一行:

primaryObject.attribute = secondaryObject.attribute;

更改如下:

id secondaryObjectAttributeValue = nil;

[secondaryContext performBlockAndWait:^
   secondaryObjectAttributeValue = secondaryObject.attribute;
];

primaryObject.attribute = secondaryObjectAttributeValue;

有没有人有更好的选择来处理同一队列中的多个NSManagedObjectContexts,而不使用NSConfinementConcurrencyType 或跳过这些乏味的performBlock: 箍?

【问题讨论】:

【参考方案1】:

我的建议是使用私有队列上下文,但要稍微改变您的方法:

    创建您的 NSOperation 子类 在main 中创建私有上下文 在 main 中的私有上下文上执行一个块 在块中调用处理实际导入的方法 将上下文保存在同一块中 退出区块 退出操作。

基本上,您的代码应该与之前相同,只是包装在 NSOperation-main 方法内的 -performBlock: 中。

【讨论】:

【参考方案2】:

这里的标准模式是通过 init 或属性将主上下文对象中对象的 objectID 传递给 NSOperation。然后在操作的main方法中创建后台上下文,然后在performBlock里面使用objectID属性将对象加载到后台上下文中,使用existingObjectWithID方法实现。

当您保存后台上下文时,可以使用通知和合并方法手动将更改合并回主上下文,或者使用您的应用委托中的此设置自动合并:

self.persistentContainer.viewContext.automaticallyMergesChangesFromParent = YES;

注意:当使用这种模式 be wary 时,以任何其他方式使用 objectID,例如获取。

【讨论】:

以上是关于NSConcurrencyType 用于在同一队列上使用独立的 NSManagedObjectContexts的主要内容,如果未能解决你的问题,请参考以下文章

linux 进程间通信方式

Azure 队列触发器不适用于 Java

电子商业汇票系统消息队列接收方法获发明专利授权

PHP进程间通信监控消息队列

初识消息队列

进程间通信(消息队列, 信号量)