gpt4 book ai didi

iphone - 为什么在保存 NSManagedObjectContext 'clean' 时出现合并错误?

转载 作者:行者123 更新时间:2023-12-03 16:17:15 26 4
gpt4 key购买 nike

预先感谢您的帮助。我今天一直在与这个问题作斗争,我认为我对框架工作原理的理解存在严重错误。

我正在开发一个核心数据应用程序,其中实体具有父/子关系。应用程序在启动时创建一个 NSManagedObjectContext (MOC)。当应用程序第一次运行时,它使用异步 block 将 plist 的内容导入到第二个 MOC(根节点是使用 URI 和 -managedObjectIDForURIRepresentation 从主 MOC 获取的:),就在该 block 完成之前保存第二个上下文。

在我的数据 Controller 中,我订阅 NSManagedObjectContextDidSaveNotification 并在发送通知时运行以下代码:

- (void)backgroundContextDidSave:(NSNotification *)notification {
if(![notification.object isEqual:self.managedObjectContext]){
if (![NSThread isMainThread]) {
[self performSelectorOnMainThread:@selector(backgroundContextDidSave:)
withObject:notification
waitUntilDone:NO];
return;
}
[self.managedObjectContext mergeChangesFromContextDidSaveNotification:notification]; ;
}
}

我已经对此代码进行了健全性检查,果然,当第二个 MOC 保存时,从执行该 block 的线程中调用它,然后将其推迟,并从主线程运行。通知对象包含第二个 MOC 中导入的所有对象,包括我们接下来要处理的两个对象。

完成后,我运行以下代码,该代码位于对象所属的 NSManagedObject 子类的方法中,它的目的只是从其父级中删除子级:

TreeEntry *oldParent=self.parent; //keep a pointer to the old parent around so we can delete self from the children

// These next four lines are a sanity check to make sure that both objects are on the same MOC we're saving
NSManagedObjectContext *selfContext=self.managedObjectContext;
NSManagedObjectContext *parentContext=self.parent.managedObjectContext;
NSManagedObjectContext *sharedContext=[[DataController sharedDataController] managedObjectContext];
assert([selfContext isEqual:parentContext] && [selfContext isEqual:sharedContext]);

// now we fault the two objects to make sure we can not possibly have them or any changes
// to them in the state of the main MOC, by this time the second MOC is long gone
[sharedContext refreshObject:self.parent mergeChanges:NO];
[sharedContext refreshObject:self mergeChanges:NO];

// up to this point, sharedContex.insertedObjects, sharedContext.updatedObects and sharedContext.deletedObjects
// have all contained no objects at all. None of the above was necessary as the MOC held no changes at all
[sharedContext saveChanges]; // we save it to, well, just to make sure I guess, I may be going crazy

// Now we carry out two changes to the objects, problem occurs if only one change is carried out,
// I'm showing both to show that there relationship is being kept consistent and valid
self.parent=nil;
[oldParent removeChild:self];


// When the next line is run the save fails with a merge conflict
[sharedContext saveChanges];

最后一次保存失败,出现 Cocoa 错误 133020,这是合并失败。错误中的两个 NSMergeConflicts 与我们正在处理的条目(self 和 self.parent)相关。

我就是不明白怎么会这样。对象在修改时没有状态,因此必须从存储中加载它们。进行了两个简单的更改,然后当立即保存它们时,会发生合并冲突。怎么可能?没有其他任何事情扰乱存储,我们刚刚从它加载了对象。

我知道我可以更改合并策略,但我不想在不了解发生了什么情况的情况下执行此操作。

有什么想法吗?我确信这只是我的心理模型,如果发生的事情是错误的,但我一整天都无法将其纠正!

最佳答案

好吧,这是我对框架如何工作的根本性误解,或者更准确地说,是对 NSManagedStoreCoordinator 缓存的工作方式的误解。

当我保存后台上下文时,更改会写入磁盘,但显然 NSManagedStoreCoordinator(两个上下文共享)不会更新或使其缓存无效。

当我刷新主 MOC 中的对象时,用于重新填充它们的数据来自缓存,其中仍然包含旧数据。它不会从磁盘重新加载。解决方案是使用 [MOC setStalenessInterval:0.0] 强制从磁盘重新加载。

关于iphone - 为什么在保存 NSManagedObjectContext 'clean' 时出现合并错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4817416/

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