根据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。)工作正常。