使用NSMainQueueConcurrencyType时,是否有必要在performBlock中读取核心数据



根据Daniel Eggert在这个问题中的回答,当将托管对象上下文与NSPrivateQueueConcurrencyType一起使用时,有必要在performBlock:performBlockAndWait: 中执行任何接触它或属于它的对象的操作

NSMainQueueConcurrencyType也是如此吗?想象一下以下代码在主线程上运行,例如在UIViewController中:

self.moc = [[[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType] autorelease];
//moc setup
__block RHWidget *widget = nil;
[self.moc performBlockAndWait:^{
    widget = [(RHWidget *)[self.moc objectWithID:self.widgetObjectID] retain];
}];
self.labelView.text = widget.descriptionString;
[widget release];

既然我们知道我们在主线程上,那么在块外使用小部件安全吗?或者有必要这样做:

__block NSString *description = nil;
[self.moc performBlockAndWait:^{
    RHWidget *widget = (RHWidget *)[self.moc objectWithID:self.widgetObjectID];
    description = [widget.descriptionString copy];
}];
self.labelView.text = description;
[description release];

如果有另一个NSManagedObjectContext,可能是私有队列类型的,在块中执行工作并将更改作为parentContext推送到self.moc,情况会改变吗?

当然,这是一个有点做作的例子,但最好将该小部件安全地传递给,例如,需要访问小部件的一些属性的模式视图控制器。我应该传递小部件的objectID,并在新视图控制器的performBlock:中重新绘制它吗?

更新:根据WWDC 2011 Session 303(iOS上核心数据的新增功能),NSMainQueueConcurrencyType旨在允许主线程上的正常消息传递;您只需要在与来自不同线程的上下文交互时使用-performBlock:。(下面仍然是我原始答案的相关部分。)


我做了一两个应用程序,它修改了Xcode的默认"主细节"应用程序模板,使"主"MOC(由应用程序委托创建并在视图控制器之间传递)仅成为主队列,并成为我用于后台操作(如从web提取导入数据)的私有队列上下文的父对象。因此,上下文及其对象的大多数使用都没有被封装在performBlock:中。(我唯一一次使用performBlock:是将后台任务上下文中的更改推回到主任务上下文中以更新UI。)工作正常。