oly*_*ise 13 concurrency multithreading core-data ios
我正在使用
-com.apple.CoreData.ConcurrencyDebug
Run Code Online (Sandbox Code Playgroud)
在我的CoreData应用程序中启动以调试并发性的论点.
在应用程序启动期间,我在主线程的托管对象上下文中执行异步提取.
// 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);
}
Run Code Online (Sandbox Code Playgroud)
从主线程调用此代码,但executeRequest:将其排入另一个线程,我理解这是正确的行为.
并发调试器不喜欢这样,说(我估计)我在这里做错了.我也尝试将[MOC performBlock:]其包装在其中也有效,但也会导致多线程违规.在这两种情况下,我得到这个:
[NSManagedObjectContext __Multithreading_Violation_AllThatIsLeftToUsIsHonor__
Run Code Online (Sandbox Code Playgroud)
我是否错误地使用异步提取,或者并发调试器在这里是错误的?
编辑:我也尝试将其包装在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];
Run Code Online (Sandbox Code Playgroud)
然后我收到通知的结果:
- (void)fetchCompletedNote:(NSNotification *)note {
NSAsynchronousFetchResult * result = note.object;
if (![cachedResults isEqualToArray:result.finalResult]){
cacheResults = result.finalResult;
[self.collectionView reloadData];
}
}
Run Code Online (Sandbox Code Playgroud)
我认为这是Apple的错误.
我提交了错误报告:https: //openradar.appspot.com/30692722
并添加了重现问题的示例项目:https: //github.com/jcavar/examples/tree/master/TestAsyncFetchCoreData
另外,如果你不想禁用只是因为这个问题的标志,你可能要调酒__Multithreading_Violation_AllThatIsLeftToUsIsHonor__的方法,NSManagedObjectContext只是这部分代码.您需要在执行请求后恢复该操作,以便在实际问题中出现违规行为.
并发调试器告诉您您正在MOC从错误的线程/队列访问。您只能调用-executeRequest: error:上下文所属的线程/队列。如果这是一个,NSMainQueueConcurrencyType那么你需要在主线程上。否则,如果它是NSPrivateQueueConcurrencyType您需要使用-performBlock:或-performBlockAndWait:在正确的队列上运行执行。
我添加了一个截图,见上文。请求从主线程排队,但在另一个线程上执行。
好的,有几件事:
-executeRequest: error:如果结果是,nil则您处于错误状态。即使成功,也可以填充错误变量。我注意到您在屏幕截图中发布的代码与您之前发布的代码不同。您-performBlock:最初是添加还是不包含它?
| 归档时间: |
|
| 查看次数: |
2139 次 |
| 最近记录: |