2013-05-03 57 views
1

据UIManagedDocument的文档中简单地提到,UIManagedDocument,后台线程和

支持异步数据写入父上下文,核心数据实际使用一对嵌套的管理对象上下文。

这是特定于UIManagedDocument或核心数据总是这样做吗?

同一份文件还指出,

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

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

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

我应该简单地替换第一线由

NSManagedObjectContext *moc = self.managedObjectContext.parentContext; 

来实现这一目标?

我想我也很困惑它会直接使用这个父上下文是“合适的”。我的意思是,这听起来像performBlock是用来卸载任务到后台队列。为什么我需要混淆父上下文?

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

回答

5

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

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

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

所以得出结论,这取决于你在操作中做了什么。主队列上下文通过不要求使用performBlock:来简化事情,因为一切都在主队列(主线程)上执行。如果你只想插入一个对象,移动到一个专用队列的好处可以忽略不计,甚至由于操作系统的上下文切换,甚至是有害的。但是,如果要执行此对象插入操作,则需要执行繁重的提升操作,您可以将其卸载到后台队列并直接在父上下文中执行。