CoreData 异步获取导致并发调试器错误 [英] CoreData asynchronous fetch causes concurrency debugger error

查看:15
本文介绍了CoreData 异步获取导致并发调试器错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用

-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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆