1

UIManagedDocument 的文档中简要提到了

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

这是特定于 UIManagedDocument 或 Core Data 的吗?

同一份文件还指出

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

这是否意味着在下面的代码中

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

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

NSManagedObjectContext *moc = self.managedObjectContext.parentContext;

做到这一点?

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

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

4

1 回答 1

6

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

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

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

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

于 2013-05-04T00:34:27.470 回答