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

前端之家收集整理的这篇文章主要介绍了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.

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

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

猜你在找的iOS相关文章