我有两个块通过 GCD 在用户定义的并发队列上同时调度。在块流中的某个时刻,它们必须访问同一组核心数据托管对象。不是显式地通过获取,而是通过已经获取的具有一对多关系集的对象。
据我了解,每个块都应该有自己的上下文,然后在完成时将两个上下文合并到主线程中的一个。
但是,我想知道创建 2 个上下文然后合并到第三个上下文的可行替代方法是执行以下操作:
- (void)someMethodThatAppliesToAdisjointSetWithRange:(NSRange)range fromSharedObject:(NSManagedObject*)someSharedObject
{
// Do some stuff...
// Create sortDescriptors
__block NSArray* entities = nil;
dispatch_sync(dispatch_get_main_queue(), ^{
entities = [[[someSharedObject valueForKey:@"sprites"] sortedArrayUsingDescriptors:sortDescriptors] retain];
entities = [entities subarrayWithRange:range]
});
for(id anEntity in entities)
{
// STRICTLY retrieve properties from the entities
// And do stuff with these, BUT DON'T modify the entities themselves.
}
// Continue doing stuff that has nothing to do with the managed objects.
}
- (void)dispatchMethod
{
dispatch_async(_concurrentQueue, ^{
[self someMethodThatAppliesToAdisjointSetWithRange:NSMakeRange(0, floor(pageData.count/2.)) fromSharedObject:someSharedObject];
});
dispatch_async(_concurrentQueue, ^{
[self someMethodThatAppliesToAdisjointSetWithRange:NSMakeRange(floor(pageData.count/2.), ceil(pageData.count/2.)) fromSharedObject:someSharedObject];
});
}
我对上面的想法是,主线程上的调度在并发流中创建了一个同步点,并且由于我什至没有修改自己的托管对象,所以应该没问题。然而,在一整天的测试中,我得到了一个核心数据“statement is still active”不一致的异常。所以现在我认为他上面的代码仍然不安全。尽管异常实际上可能是由应用程序中的其他代码引起的。
有什么想法吗?