【问题标题】:UIManagedDocument, background thread and parent contextUIManagedDocument、后台线程和父上下文
【发布时间】:2013-05-03 23:53:27
【问题描述】:

UIManagedDocument 的文档中简要提到了

为了支持异步数据写入,Core Data 实际上使用了一对嵌套的托管对象上下文。

特定于 UIManagedDocument 或 Core Data 是否总是这样做?

同一文件还指出

如果合适,您可以将数据从后台线程直接加载到 parent 上下文。

是不是意味着在下面的代码中

NSManagedObjectContext *moc = self.managedObjectContext;
[moc performBlock:^() {
    Record *record = [NSEntityDescription
        insertNewObjectForEntityForName:@"Record" 
                 inManagedObjectContext:moc];
}];

我应该简单地将第一行替换为

NSManagedObjectContext *moc = self.managedObjectContext.parentContext;

要做到这一点?

我想我也对直接使用这个父上下文在哪里“合适”感到困惑。我的意思是,这听起来已经像是 performBlock 用于将任务卸载到后台队列。为什么我需要弄乱父上下文?

如果有人为我澄清这一切,我将不胜感激。

【问题讨论】:

    标签: ios core-data uimanageddocument


    【解决方案1】:

    这是UIManagedDocument 的实现细节,但这是Core Data 应用程序中的常见设计模式。 UIManagedDocumentmanagedObjectContext是并发类型为NSMainQueueConcurrencyType的上下文,而parentContext是并发类型为NSPrivateQueueConcurrencyType的上下文。

    有关并发类型的更多信息,请参阅here。简而言之,父上下文使用后台队列进行操作,而子上下文使用主队列。

    通常,当您希望在后台队列中以非阻塞方式执行某些操作时,您希望直接使用父上下文。例如,如果您希望执行一个漫长而困难的获取请求,您可以直接在父上下文中执行它。请记住,返回的对象在上下文之间不可互换,因此您必须将返回的对象从一个上下文重新提取到另一个上下文中(但现在可以使用[NSPredicate predicateWithFormat:@"SELF IN %@", fetchedObjectsFromAnotherContext] 轻松执行重新获取)。

    因此,总而言之,这取决于您在操作中执行的操作。主队列上下文不需要您使用performBlock:,从而大大简化了事情,因为一切都在主队列(主线程)上执行。如果您只想插入一个对象,那么移动到私有队列的好处将是微不足道的,甚至由于操作系统的上下文切换甚至是有害的。但是,如果为了执行此对象插入,您需要执行繁重的工作,您可以将其卸载到后台队列并直接在父上下文中执行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-19
      • 1970-01-01
      • 2014-10-04
      • 2012-07-06
      相关资源
      最近更新 更多