如何从子队列中保存父NSManagedObjectContext?

时间:2012-11-23 17:53:15

标签: ios core-data

我有以下设置:

NSManagedObjectContext *parent = [[NSManagedObjectContext alloc] 
                            initWithConcurrencyType:NSMainQueueConcurrencyType];
// other setup for parent

NSManagedObjectContext *child = [[NSManagedObjectContext alloc] 
                          initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[child setParentContext:parent];

我想要的是在孩子保存时保存父母,所以目前我做的是这样的事情:

[child performBlock^{
      [child save:nil];
      [parent performBlock:^{
          [parent save:nil];
      }
}];

这是我的安全,并在上下文自己的队列中调用save。这有必要吗?我可以这么做:

[child performBlock^{
     [child save:nil];
     [parent save:nil];
}];

2 个答案:

答案 0 :(得分:2)

不,你不能使用第二种变体。您将对与子上下文关联的队列上的父上下文执行save操作,而不是主队列。

这意味着save操作将在(可能)不同于主线程的线程上执行,这是不允许的,因为托管对象上下文不是线程安全的。

另见Concurrency Support for Managed Object Contexts 在OS X v10.7和iOS 5.0的核心数据发行说明中

  

使用基于队列的并发类型的上下文   结合两种新方法:performBlock:和   performBlockAndWait:。 ......唯一的例外是:如果您的代码是   在主线程上执行,您可以调用主队列上的方法   直接使用样式上下文而不是使用基于块的API。

     

performBlock:performBlockAndWait:确保阻止操作   在为上下文指定的队列上执行。 ...

答案 1 :(得分:1)

你需要调用主上下文来保存它自己的队列,我假设你使用主队列作为父上下文,所以你可以这样做;

[child performBlock^{
     [child save:nil];
     [parent performSelectorOnMainThread:@selectorr(save:) withObject:nil waitUntilDone:NO];
}];

此代码将确保您的父managedObjectContxt将始终保存在主线程中。我认为将主上下文始终放在主线程上是一个好主意,这使得在不同线程之间轻松实现同步。