CoreData异步提取会导致并发调试程序错误 [英] CoreData asynchronous fetch causes concurrency debugger error

查看:114
本文介绍了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天全站免登陆