Ios NSMergeConflict(两个线程)-设置合并策略不需要';解决不了

Ios NSMergeConflict(两个线程)-设置合并策略不需要';解决不了,ios,multithreading,cocoa-touch,core-data,conflict,Ios,Multithreading,Cocoa Touch,Core Data,Conflict,好吧,这让我快发疯了 我有两个线程使用UImanageddocument,一个在用户进行选择的主上下文上,后台线程使用自己的moc根据时间戳将数据与服务器同步 不过,当我: 1.在主上下文中添加对象 2.后台同步 3.从后台保存 4.再次尝试更改同一对象,现在从主上下文-主线程开始 我遇到了一场冲突 我将包括一些我的代码,不包括很多不相关的代码,向您展示我如何初始化上下文,希望有人能给我一些启发。我知道核心数据在这些领域很棘手 在主线程上(在ApplicationIDFinishLoadingW

好吧,这让我快发疯了

我有两个线程使用UImanageddocument,一个在用户进行选择的主上下文上,后台线程使用自己的moc根据时间戳将数据与服务器同步

不过,当我: 1.在主上下文中添加对象 2.后台同步 3.从后台保存 4.再次尝试更改同一对象,现在从主上下文-主线程开始

我遇到了一场冲突

我将包括一些我的代码,不包括很多不相关的代码,向您展示我如何初始化上下文,希望有人能给我一些启发。我知道核心数据在这些领域很棘手

在主线程上(在ApplicationIDFinishLoadingWithOptions中):

后来:

- (void)handleDataModelChange:(NSNotification *)note
{
    [self save];
}

-(void) save
{
        [self.database saveToURL:self.database.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:^(BOOL success) {
            batch_save=!success;
            NSLog(@"save success %d",success);
        }];
}
在背景线程上:

dispatch_queue_t fetchQ = dispatch_queue_create("syncing list", NULL);
dispatch_async(fetchQ, ^   // ***********  BACKGROUND THREAD ***********
{
    AppDelegate *delegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
    NSManagedObjectContext *backgroundMOC2;
    backgroundMOC2=[[NSManagedObjectContext alloc] init];
    [backgroundMOC2 setPersistentStoreCoordinator:delegate.mainManagedObjectContext.persistentStoreCoordinator];
    [backgroundMOC2 setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
    [delegate.mainManagedObjectContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
    [[NSNotificationCenter defaultCenter] addObserver:delegate.mainManagedObjectContext selector:@selector(mergeChangesFromContextDidSaveNotification:) name:NSManagedObjectContextDidSaveNotification object:backgroundMOC2];


    ** pseudo-code: 
       perform fetch request from CD
       submit data to server with POST request (synchronously)
       retrieve JSON reply from server
       update what's needed in CD objects
    ** end of pseudo code

   [backgroundMOC2 save:nil];
   [[NSNotificationCenter defaultCenter] removeObserver:delegate.mainManagedObjectContext name:NSManagedObjectContextDidSaveNotification object:backgroundMOC2];
    });
dispatch_release(fetchQ);
我尝试了所有类型的合并策略常量,但都没有效果

我正在获取此信息,但文件未保存:

冲突列表=( “NSManagedObject(0x119aea80)的NSMergeConflict(0x1a9ee1e0),对象ID为'0x9dcec90',旧版本为10,新版本为11,旧对象快照={\n displayName=\”\”;\n machineName=kiygrdtdvltqb;\n note=\”;\n product=\“0x11967ab0\”;\n public=1;\n published=1;\n quantity=3;\n registeredTo=”\“;\n registeredToEmail=\”;\n registeredtoote=\”;\n status=\“在注册表上”;\n upDate=\“2013-03-07 10:22:01+0000\”;\n wishList=\”;\n}和新缓存行={\n displayName=\”;\n machineName=kiygrdtvltqb;\n note=\”;\n product=\“0x1a9ee3d0\”;\n public=1;\n published=1;\n quantity=3;\n registeredTo=\“\”;\n registeredToEmail=\“\”;\n registeredToNote=\“\”;\n status=\“ON REGISTRY\”;\n upDate=\“2013-03-07 10:22:03+0000\”;\n wishList=\“\”;\n}” ); }

顺便说一句,我看到的新旧对象之间的唯一区别是指向“产品”的指针。 这可能是我的问题吗

另一个可能的线索是,只有在添加了新对象,并且只有在后台同步发生之后,才会发生这种情况。 如果我停止应用程序并重新加载它(重新加载持久存储),我现在可以毫无问题地编辑现有对象,并且可以无问题地多次同步它

谢谢大家

好的朋友们

经过一个月的心碎之后,有了一个解决方案,,我猜不到什么。事实上,我与苹果公司开启了一个支持事件,他们解决了这个问题

下面是:

在为主托管对象上下文设置合并策略时,有一个名为parentContext的属性。我仍然不太清楚该属性是什么,因为这方面的文档很少。但是这确实解决了我的问题。 请注意,在我的工作流程中,我创建了一个NSManagedDocument并从中提取了上下文。我认为大多数人的做法是相反的(大多数人不使用manageddocument)

而不是

   [self.mainManagedObjectContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
我现在使用:

   NSManagedObjectContext *parentContext = delegate.mainManagedObjectContext.parentContext;
    [parentContext performBlockAndWait:^{
        [parentContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
    }];
块是一种预防措施,确保在适当的线程中执行,重要的是将合并策略设置为所需上下文的parentContext

就我个人而言,我必须加上两个大大的嘘声: 1.嘘我,因为我使用了NSManagedDocument,虽然它有点过时,只是因为我发现了使用它的好例子。
2.苹果在该领域非常缺乏文档,这让我大吃一惊。我花了数周时间阅读了ManagedObjectContext,今天是我第一次认识parentContext属性。

hi@llan lewin,你能先看看这个链接吗?谢谢!这绝对解决了我的问题。关于父上下文,你可以在以下网站阅读:(第节:使用托管文档的托管对象上下文。)Hi Ilan,在您的回答中,您提到了这种方法(即在performBlockAndWait中设置合并策略)通过创建NSManagedDocument获取上下文时非常有用。我没有使用此工作流。我是否也应该将其添加到工作流中?或者是否有其他方法?因此,必须始终在父ctx上设置合并策略?何时设置合并策略?何时?!
   NSManagedObjectContext *parentContext = delegate.mainManagedObjectContext.parentContext;
    [parentContext performBlockAndWait:^{
        [parentContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
    }];