在私有/后台队列上创建 NSManagedObjectContext:怎么办?

Posted

技术标签:

【中文标题】在私有/后台队列上创建 NSManagedObjectContext:怎么办?【英文标题】:Creating a NSManagedObjectContext on a private/background queue: how to do? 【发布时间】:2014-04-22 22:56:05 【问题描述】:

我对如何在主线程以外的其他线程上创建MOC 感到困惑。

一方面,在the doc,可以阅读

这样做的结果是上下文假定默认所有者是 分配它的线程或队列——这由线程决定 调用它的 init 方法。因此,您不应该初始化 一个线程上的上下文,然后将其传递给另一个线程。

但另一方面,我看到了一个辅助MOC 的代码是通过以下方式创建的,在主线程上

    NSManagedObjectContext *parentContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];

    [parentContext performBlockAndWait:^
        [parentContext setUndoManager:nil]; // no point in it supporting undo
        [parentContext setPersistentStoreCoordinator:coordinator];
    ];

那么,创建辅助MOC 的好方法是什么?也许我应该准确地说,这个辅助MOC 是项目中心类的@property(例如AppDelegate)。

【问题讨论】:

它们的相对并发类型都是正确的。第一个引用NSConfinementConcurrencyType,另一个引用NSPrivateQueueConcurrencyType(上下文绑定到执行队列)。文档很旧,不包括“新”队列并发类型。 好吧,我想第二种方法最好,不是吗? 【参考方案1】:

这些文档充其量是模棱两可的。

在我的测试中,您不需要使用队列将NSManagedObjectContext 附加到其父级或NSPersistentStoreCoordinator

如果您正在执行NSConfinmentConcurrencyType,我会在创建它的线程上设置父级或协调器(因为那是可以使用它的线程)。

如果您正在执行NSPrivateQueueConcurrencyType,我也会在创建它的线程上设置父级或协调器。 NSManagedObjectContext 的使用被限制或限制在专用队列中。我将用法定义为执行提取、删除对象等。配置NSManagedObjectContext 不受限制。

这当然不在文档中,但结果是通过测试产生的,当访问 NSManagedObjectContext 错误导致异常时。

【讨论】:

谢谢。当您说:“NSManagedObjectContext 的使用被限制或限制在私有队列中”时,您的意思是您必须使用 performBlock:, ... 方法,不是吗? 如果您使用的是私人账户,那么是的,-performBlock:。如果您使用的是受限 MOC,则不,您应该在直接创建它的线程上使用它。 @Marcus-s-zarra 你能用一些代码更新你的答案吗(如果可能的话)。这将是一个完美的答案!谢谢!

以上是关于在私有/后台队列上创建 NSManagedObjectContext:怎么办?的主要内容,如果未能解决你的问题,请参考以下文章

无权访问私有 MSMQ

需要帮助设置后台托管对象上下文。在 FRC controllerDidChangeContent 上获取异常

从后台队列调用时,核心数据 NSManagedObjectContext 保存永远不会返回

关于访问MSMQ远端私有队列的一点经验

CoreData从后台线程读取数据仍然阻塞UI界面的原因及解决

私有队列 NSManagedObjectContext 在无限循环中保存结束