我有以下设置:
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];
}];
答案 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将始终保存在主线程中。我认为将主上下文始终放在主线程上是一个好主意,这使得在不同线程之间轻松实现同步。