CoreDataasynchronous获取导致并发debugging器错误
我正在使用
-com.apple.CoreData.ConcurrencyDebug
启动时debugging我的CoreData应用程序中的并发性。
在应用程序启动期间,我对主线程的托pipe对象上下文执行asynchronous获取。
// 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:
将它排入另一个线程,我知道这是正确的行为。
并发debugging器不喜欢这个,说(我认为)我在这里做错了什么。 我也试过在[MOC performBlock:]
包装这也是[MOC performBlock:]
,但也会导致multithreading违规。 在这两种情况下,我得到这个:
[NSManagedObjectContext __Multithreading_Violation_AllThatIsLeftToUsIsHonor__
我是使用asynchronous提取不正确,还是在这里的并发debugging器错误?
编辑:我也试图包装它在MOC performBlock
应该确保它从主线程调用。 在任何情况下,调用都从主线程中排队 ,但在其他地方执行。
编辑:这里是获取请求:
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];
然后我收到通知的结果:
- (void)fetchCompletedNote:(NSNotification *)note { NSAsynchronousFetchResult * result = note.object; if (![cachedResults isEqualToArray:result.finalResult]){ cacheResults = result.finalResult; [self.collectionView reloadData]; } }
我认为这是苹果的错误。
我提交了错误报告: https : //openradar.appspot.com/30692722
并添加了重现问题的示例项目: https : //github.com/jcavar/examples/tree/master/TestAsyncFetchCoreData
另外,如果你不想因为这个问题而禁用标志,那么你可能需要在NSManagedObjectContext
上__Multithreading_Violation_AllThatIsLeftToUsIsHonor__
方法来完成这部分代码。 你需要在请求被执行后恢复,这样你会遇到真正的问题。
并发debugging器告诉你,你是从错误的线程/队列访问MOC
。 您只能在上下文所属的线程/队列上调用-executeRequest: error:
如果这是一个NSMainQueueConcurrencyType
那么你需要在主线程上。 否则,如果是NSPrivateQueueConcurrencyType
,则需要使用-performBlock:
或-performBlockAndWait:
在正确的队列上运行该执行。
我添加了一个截图,见上文。 请求从主线程中排队,但在另一个线程上执行。
好的,有几件事情:
- 那是破产/崩溃的线路还是你看到错误输出?
- 你的error handling是不正确的。 您应该查看
-executeRequest: error:
的结果-executeRequest: error:
如果结果nil
则表明您处于错误状态。 即使成功,也可以填充错误variables。
我注意到您在屏幕截图上发布的代码与之前发布的代码不同。 你添加了-performBlock:
还是只是不包含它呢?