CoreData异步提取会导致并发调试程序错误 [英] CoreData asynchronous fetch causes concurrency debugger error
问题描述
我正在使用
-com.apple.CoreData.ConcurrencyDebug
在我的CoreData应用程序中启动以调试并发性的参数。
argument on launch to debug concurrency in my CoreData app.
在应用程序启动期间,我在主线程的托管对象上下文中执行异步提取。
During app launch, I perform an asynchronous fetch on the main thread's managed object context.
// set up the async request
NSError * error = nil;
[MOC executeRequest:asyncFetch error:&error];
if (error) {
NSLog(@"Unable to execute fetch request.");
NSLog(@"%@, %@", error, error.localizedDescription);
}
此代码从主线程调用,但 executeRequest:
将它排入另一个线程,我理解这是正确的行为。
This code is called from the main thread, but executeRequest:
enqueues it to another thread, which I understand to be the correct behavior.
并发调试器不喜欢这样,说(我估计)我在这里做错了。我也尝试在 [MOC performBlock:]
中包装它,这也有效,但也会导致多线程违规。在这两种情况下,我得到这个:
The concurrency debugger doesn't like this, saying (I reckon) that I'm doing something wrong here. I've also tried wrapping this in [MOC performBlock:]
which also works, but also causes a multithreading violation. In both cases I get this :
[NSManagedObjectContext __Multithreading_Violation_AllThatIsLeftToUsIsHonor__
我是否错误地使用了异步提取,或者这里的并发调试器是错误的?
Am I using async fetches incorrectly, or is the concurrency debugger wrong here?
编辑:我也尝试将其包装在MOC performBlock
中,这应该确保从主要调用它线。在任何情况下,调用都是从主线程排队,但在其他地方执行。
EDIT : I've also tried wrapping it in MOC performBlock
which should ensure that it gets called from the main thread. In any case, the call is enqueued from the main thread, but executed elsewhere.
编辑:这是获取请求:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"MyEntity"];
NSPredicate * pred = [NSPredicate predicateWithFormat:@"boolProperty == YES"];
fetchRequest.predicate = pred;
NSSortDescriptor * sort = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
fetchRequest.sortDescriptors = @[sort]; fetchRequest.propertiesToFetch = @[@"prop1", @"prop2", @"prop3", @"prop4"];
NSPersistentStoreAsynchronousFetchResultCompletionBlock resultBlock = ^(NSAsynchronousFetchResult *result) {
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:kFetchCompleteNotification object:result];
});
};
NSAsynchronousFetchRequest *asyncFetch = [[NSAsynchronousFetchRequest alloc]
initWithFetchRequest:fetchRequest
completionBlock:resultBlock];
然后我收到通知的结果:
Then I receive the results from the notification:
- (void)fetchCompletedNote:(NSNotification *)note {
NSAsynchronousFetchResult * result = note.object;
if (![cachedResults isEqualToArray:result.finalResult]){
cacheResults = result.finalResult;
[self.collectionView reloadData];
}
}
推荐答案
我认为这是Apple的错误。
I think this is Apple's bug.
我提交了错误报告:
https:/ /openradar.appspot.com/30692722
并添加了重现问题的示例项目:
https://github.com/jcavar/examples/tree/master/TestAsyncFetchCoreData
and added example project that reproduces issue: https://github.com/jcavar/examples/tree/master/TestAsyncFetchCoreData
此外,如果您不想仅因为此问题而禁用标记,则可能需要在 NSManagedObjectContext上调用
仅适用于此部分代码。 __ Multithreading_Violation_AllThatIsLeftToUsIsHonor __
方法
您需要在执行请求后还原,以免因实际问题而违规。
Also, if you don't want to disable flag just because of this issue you may want to swizzle __Multithreading_Violation_AllThatIsLeftToUsIsHonor__
method on NSManagedObjectContext
just for this part of code.
You need to revert that after request is executed so you get violations for real issues.
这篇关于CoreData异步提取会导致并发调试程序错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!