gpt4 book ai didi

ios - 在 performBlockAndWait block 内执行获取请求时核心数据死锁

转载 作者:技术小花猫 更新时间:2023-10-29 11:08:06 24 4
gpt4 key购买 nike

我遇到了无法解决的 Core Data 问题。我以艰难的方式了解了核心数据中的并发问题,因此我非常小心,只在 performBlock:performBlockAndWait: block 中执行任何核心数据操作。

这是我的代码:

/// 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];

这很有趣:似乎两个线程都无法获取持久存储协调器上的一些锁来执行获取请求。

我所有的上下文都是 NSPrivateQueueConcurrencyType

我无法确定为什么要锁定应用程序以及我应该采取哪些不同的措施。我对 Stack Overflow 的研究没有给我任何帮助,因为大多数人通过在 MOC 队列上分派(dispatch)获取请求来修复所有锁,而我已经这样做了。

我将不胜感激有关此问题的任何信息。欢迎提供文档链接和其他长读物:我渴望了解更多关于各种并发问题和策略的信息。

最佳答案

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 - 在 performBlockAndWait block 内执行获取请求时核心数据死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22041670/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com