1

我有以下设置:

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];
}];
4

2 回答 2

2

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

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

另请参阅OS X v10.7 和 iOS 5.0 的核心数据发行说明中对托管对象上下文的并发支持

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

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

于 2012-11-23T18:44:15.350 回答
1

您需要调用主上下文以保存在自己的队列中,我假设您将主队列用于父上下文,这样您就可以这样做;

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

此代码将确保您的父 managedObjectContxt 将始终保存在主线程中。而且我认为将主上下文始终放在主线程上是一个好主意,这样可以很容易地在不同线程之间进行同步。

于 2012-11-23T20:24:06.013 回答