gpt4 book ai didi

ios - 使用并发类型 NSPrivateQueueConcurrencyType 保存上下文时出现死锁

转载 作者:行者123 更新时间:2023-11-29 11:11:00 24 4
gpt4 key购买 nike

这两天我一直在尝试让 Core Data 与多线程一起工作。我尝试使用 NSOperations 的标准线程限制方法、合并通知、使用 objectWithId、每个线程的上下文字典,但我仍然遇到奇怪的死锁、不一致的异常和一堆其他讨厌的东西。这让我发疯......此外,当两个线程都可能对共享持久存储进行更改时,我找不到关于如何在两个线程中管理上下文的单个示例或解释......

我尝试使用新的 iOS 5 方法,这应该更容易,但我仍然遇到错误。第一个问题是保存上下文时的死锁。我删除了所有不必要的代码,并且在足够快地执行这段代码时仍然会出现死锁(通过快速点击按钮):

    NSManagedObjectContext *context = [StoreDataRetriever sharedRetriever].managedObjectContext;

for (int i = 0; i < 5; i++) {
NSError *error = nil;
NSLog(@"Main thread: %@, is main? %d", [NSThread currentThread], [NSThread isMainThread]);
BOOL saveOK = [context save:&error];

if (!saveOK) {
NSLog(@"ERROR!!! SAVING CONTEXT IN MAIN");
}

[context performBlock:^{

NSLog(@"Block thread: %@", [NSThread currentThread]);

NSError *error = nil;
BOOL savedOK = NO;

savedOK = [context save:&error];

if (!savedOK) {
NSLog(@"ERROR!!! SAVING CONTEXT IN BLOCK");
}
}];
}

数据库没有其他变化,什么都没有,只是保存上下文。这段代码有什么问题?它应该是什么样子?

注意:[StoreDataRetriever sharedRetriever].managedObjectContext 是在 appDelegate 中使用 initWithConcurrencyType:NSPrivateQueueConcurrencyType 创建的。

最佳答案

这段代码是怎么回事?您正在线程上同步保存上下文,然后安排在上下文专用队列上保存。 5次。所以基本上,您很可能有两个保存操作,一个是同步的,一个是异步的,它们相互冲突。

这显然是一个问题。您不应该使用该队列之外的专用队列保存上下文。如果上下文队列上没有计划 block ,它将与当前上下文实现一起工作。但这仍然是错误的。


for (int i = 0; i < 5; i++) {
NSLog(@"Main thread: %@, is main? %d", [NSThread currentThread], [NSThread isMainThread]);
__block NSError *error = nil;
__block BOOL saveOK = YES;
[context performBlockAndWait: ^{
saveOK = [context save: &error];
}];

if (!saveOK) {
NSLog(@"ERROR!!!");
}

使用该代码,您可以同步执行保存操作,而且很可能是在同一个线程上 - 感谢 GCD - 节省了上下文切换和同步内容,并且没有任何同时在该上下文上运行两个操作的风险。

同样的规则适用于使用 NSMainQueueConcurrencyType 时,但有一个异常(exception)。该队列仅绑定(bind)到主线程和主线程。您可以使用来自任何具有 performBlock 和 performBlockAndWait 的线程的主队列在上下文上调度 block ,例如 NSPrivateQueueConcurrencyType,并且(异常(exception):)您可以直接在主线程上使用上下文。

NSConfinementConcurrencyType 将上下文绑定(bind)到特定线程,您不能使用 GCD 或 block 来处理此类上下文,只能使用绑定(bind)线程。截至目前,几乎没有理由使用该并发模型。如果必须,请使用它,但如果不是绝对必须,则不要。


编辑

这是一篇关于多上下文设置的非常好的文章:http://www.cocoanetics.com/2012/07/multi-context-coredata/

关于ios - 使用并发类型 NSPrivateQueueConcurrencyType 保存上下文时出现死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11580667/

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