繁体   English   中英

保存NSManagedObjectContext这个'干净'时为什么会出现合并错误?

[英]Why am I getting a merge error when saving an NSManagedObjectContext this 'clean'?

提前感谢您的帮助。 我今天花了很多时间与此作斗争,我认为我对框架的运作方式有一些严重的错误。

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

在我的数据控制器中,我订阅了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保存时,从执行块的线程调用它,然后延迟,并从主线程运行。 通知对象包含在第二个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]强制从磁盘重新加载。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM