ios – 在执行performBlockAndWait块内的提取请求时,Core数据死锁

我遇到了Core Data的问题,我无法解决.我在Core Data中学习了并发问题,所以我非常小心,只执行performBlock中的任何核心数据操作:performBlockAndWait:blocks.

这里我的代码:

/// Executes a fetch request with given parameters in context's block.
+ (NSArray *)executeFetchRequestWithEntityName:(NSString *)entityName
                                 predicate:(NSPredicate *)predicate
                                fetchLimit:(NSUInteger)fetchLimit
                            sortDescriptor:(NSSortDescriptor *)sortDescriptor
                                 inContext:(NSManagedObjectContext *)context{
    NSCAssert(entityName.length > 0,@"entityName parameter in executeFetchRequestWithEntityName:predicate:fetchLimit:sortDescriptor:inContext:\
          is invalid");

    __block NSArray * results = nil;

    NSPredicate * newPredicate = [CWFCoreDataUtilities currentUserPredicateInContext:context];
    if (predicate){
        newPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[newPredicate,predicate]];
    }

    [context performBlockAndWait:^{

        NSFetchRequest * request = [NSFetchRequest fetchRequestWithEntityName:entityName];
        request.fetchLimit = fetchLimit;
        request.predicate = newPredicate;
        if (sortDescriptor) {
            request.sortDescriptors = @[sortDescriptor];
        }

        NSError * error = nil;
        results = [context executeFetchRequest:request error:&error];

        if (error){
            @throw [NSException exceptionWithName:NSInternalInconsistencyException
                                           reason:@"Fetch requests are required to succeed."    
                                         userInfo:@{@"error":error}];
             NSLog(@"ERROR! %@",error);
        }

        NSCAssert(results != nil,@"Fetch requests must succeed");
    }];

    return results;
}

当我从两个不同的线程同时输入这个方法并通过两个不同的上下文时,这个行会导致死锁:results = [context executeFetchRequest:request error:& error];

这是有趣的:似乎两个线程都不能在Persistent Store协调器上获取一些锁,以执行提取请求.

我的所有上下文都是NSPrivateQueueConcurrencyType.

我不能把我的手指,为什么我锁定的应用程序,我该怎么做不同的.我对Stack Overflow的研究没有给我任何东西,因为大多数人通过在MOC的队列上发送抓取请求来修复所有的锁,我已经做了.

我会感谢有关这个问题的任何信息.随时提供文档链接和其他长的阅读:我渴望了解更多关于所有类型的并发问题和策略.

解决方法

Which is interesting: it seems like both threads cannot acquire some lock on the Persistent Store Coordinator in order to execute a fetch request.

持久存储协调器是一个串行队列.如果一个上下文正在访问它,则另一个上下文将被阻止.

Apple Docs

Coordinators do the opposite of providing for concurrency—they serialize operations. If you want to use multiple threads for different write operations you use multiple coordinators. Note that if multiple threads work directly with a coordinator,they need to lock and unlock it explicitly.

如果您需要并发执行多个后台提取请求,则需要多个持久存储协调器.

多个协调员将使您的代码稍微复杂一点,但如果可能,应该避免.你真的需要同时做多个提取吗?你能做一个更大的提取,然后过滤内存中的结果?

相关文章

UITabBarController 是 iOS 中用于管理和显示选项卡界面的一...
UITableView的重用机制避免了频繁创建和销毁单元格的开销,使...
Objective-C中,类的实例变量(instance variables)和属性(...
从内存管理的角度来看,block可以作为方法的传入参数是因为b...
WKWebView 是 iOS 开发中用于显示网页内容的组件,它是在 iO...
OC中常用的多线程编程技术: 1. NSThread NSThread是Objecti...