我正在使用
-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.
我提交了错误报告:openradar.appspot/30692722
并添加了重现问题的示例项目:github/jcavar/examples/tree/master/TestAsyncFetchCoreData
and added example project that reproduces issue: github/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 异步获取导致并发调试器错误
发布评论