gpt4 book ai didi

ios - 核心数据和竞争条件

转载 作者:行者123 更新时间:2023-12-01 16:59:49 24 4
gpt4 key购买 nike

问题:如何将核心日期合并更改为相同的 NSManagedObject在两个不同的线程中?线程改变不同的属性,这些属性的任何组合都是有效的。

有一个应用程序(至少)有两个线程,即 UI 线程和后台线程。
一个所谓的DocumentNSManagedObject 的子类.
一个 Document具有三个属性,attrA , attrBattrC .

后台线程读取attrA并写attrB , 像:

doc.attbB = md5(doc.attrA);

(在实践中,它更复杂,更耗时,但你明白了)。

UI 线程显示所有 attrA , attrBattrC给用户并允许用户更改 attrAattrC . (有一段时间, attrB 的值是无效的。)

我强调只有 UI 线程写入 attrA ,并且只有后台线程写入 attrB .

现在,用户更改 attrC计算前 attrB完成了。
后台线程尝试保存 attrB并得到一个错误。
我现在做的是:
if(!saved) {
// I did try to check that it's *that* kind of error,
// but that's iOS5-specific, while I need 4.3
// (comments on error type checking in 4.3 are welcome).
// Anyway, finally it was this:
id tmp = doc.attrB;
[[doc managedObjectContext] refreshObject:doc mergeChanges:NO];
doc.attrB = tmp;
BOOL saved = [context save:&error];
// NSLog if it still failed
}

在一般情况下,这不起作用。

首先,如果在这些行之间进行更多更改会发生什么:
    [[doc managedObjectContext] refreshObject:doc mergeChanges:NO];
doc.attrB = tmp;
// more changes happen here!!!
BOOL saved = [context save:&error];

是的,我可以暂时更换 if ,但这不是一般情况下的解决方案。如果更改重复发生,这可能是一个无限循环。

其次,UI 线程也可能正在尝试保存一些东西。在其中一个类中,我看到了旨在合并更改的代码,
#pragma mark Changes Propagation

- (void)__contextDidSave:(NSNotification*)notification
{
[parent performSelectorOnMainThread:@selector(__mergeChanges:) withObject:notification waitUntilDone:NO];
}

- (void)__mergeChanges:(NSNotification*)notification
{
[objectContext mergeChangesFromContextDidSaveNotification:notification];
if (parent) {
[parent __mergeChanges:notification];
}
}

据我了解, __mergeChanges将在正确的线程上运行,但不会立即运行; UI 线程可能会尝试保存 attrA 中的更改。和 attrC后台线程更改后 attrB但在 __mergeChanges 之前正在运行。

这是一个经典的比赛条件。

问题:我如何 正确 将核心日期合并更改为相同的 NSManagedObject在两个不同的线程中? (线程改变不同的属性,这些属性的任何组合都是有效的,但 Core Data 不知道。)

最佳答案

我不是核心数据方面的专家,但我猜你可以使用同步指令:

// UI Thread
@synchronized(AN_INSTANCE_OF_ANY_OBJECT) {
// your first thread's code goes here
}

// Background Thread
@synchronized(THE_SAME_INSTANCE_OF_THE_OBJECT) {
// your second thread's code goes here
}

如果任何其他线程正在执行其范围,这应该会停止任何线程的执行,请注意实例应该是相同的,因此如果您无法访问该实例,您可以使用公共(public)静态实例,这通常可以帮助我做到这一点。

关于ios - 核心数据和竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8178817/

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