核心数据编程指南中有关于线程限制模式的 主题,它说
您必须在将要使用的线程上创建托管上下文。如果您使用 NSOperation,请注意它的 init 方法是在与调用者相同的线程上调用的。因此,您不能在队列的 init 方法中为队列创建托管对象上下文,否则它与调用者的线程相关联。相反,您应该在 main(对于串行队列)或 start(对于并发队列)中创建上下文。
我就是不明白这是为什么?区别在哪里?
核心数据编程指南中有关于线程限制模式的 主题,它说
您必须在将要使用的线程上创建托管上下文。如果您使用 NSOperation,请注意它的 init 方法是在与调用者相同的线程上调用的。因此,您不能在队列的 init 方法中为队列创建托管对象上下文,否则它与调用者的线程相关联。相反,您应该在 main(对于串行队列)或 start(对于并发队列)中创建上下文。
我就是不明白这是为什么?区别在哪里?
它说明了为什么在您引用的文档中非常清楚。操作init
方法在调用者线程上运行,而main
方法中发生的工作可能在另一个线程上运行。
由于您不能在线程之间共享托管对象上下文,因此您需要在将要使用它的同一线程上创建它。因此,如果您在操作中使用它,您需要确保在操作运行所在的同一线程上创建上下文。
串行操作在 main 中创建上下文的原因是它们运行默认实现,而您在实现并发操作时start
覆盖。start
您可以在并发编程指南中阅读有关并发操作如何工作的更多信息(提示:搜索“开始”)
大卫是对的。
文档说,例如,如果您NSOperation
调用了一个子类MyOperation
并且您覆盖了init
如下方法
- (id)init
{
if(self = [super init]) {
// your context here
}
return self;
}
然后,如果您在主线程中实例化该操作,例如
MyOperation* op = // alloc-init
您创建的上下文与主线程相关联,而不是与操作所在的线程相关联。
当您对托管对象执行更改(删除、更新等)时,可能会发生奇怪的事情,因为您是在后台更改它们,但您访问的是主线程中的上下文。
main
而是覆盖并在那里创建上下文:
- (void)main
{
// your context here
}