iOS 7 上的 NS 合并冲突

Posted

技术标签:

【中文标题】iOS 7 上的 NS 合并冲突【英文标题】:NSMergeConflict on iOS7 【发布时间】:2013-10-04 10:25:24 【问题描述】:

我已经更新了我的应用程序以支持 ios 7,并且遇到了在我的 [context save]; 的一个屏幕上出现以下错误的问题:

NSCocoaErrorDomain Code=133020 "The operation couldn’t be completed. (Cocoa error 133020.)" UserInfo=0x1115a6d0 conflictList=(
"NSMergeConflict (0x1115a670) for NSManagedObject (0xf25c850) with objectID '0xf25c070 <x-coredata://76AF57C8-F7FF-4880-B06B-63F8B780C96D/Screen/p7>' with oldVersion = 5 and newVersion = 6 
and old object snapshot = \n    index = 3;\n    message = \"<null>\";\n    status = 0;\n and new cached row = \n    index = 3;\n    message = \"<null>\";\n    status = 0;\n"

在 iOS6 上不会出现此问题。

更新: managedObjectContext 的代码

-(NSManagedObjectContext *)managedObjectContextForCurrentThread
if ([NSThread isMainThread])

    NSManagedObjectContext *parentContext = self.mainManagedObjectContext.parentContext;
    [parentContext performBlockAndWait:^
        NSMergePolicy *mergePolicy = [[NSMergePolicy alloc] initWithMergeType:NSMergeByPropertyObjectTrumpMergePolicyType];
        [[self mainManagedObjectContext] setMergePolicy:mergePolicy];
    ];
    return self.mainManagedObjectContext;

else

    NSMutableDictionary *threadDict = [[NSThread currentThread] threadDictionary];
    NSManagedObjectContext *threadContext = [threadDict objectForKey:kCGMManagedObjectContextKey];
    if (threadContext == nil)
    
        threadContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
        NSManagedObjectContext *parentContext = self.mainManagedObjectContext.parentContext;
        [parentContext performBlockAndWait:^
            NSMergePolicy *mergePolicy = [[NSMergePolicy alloc] initWithMergeType:NSMergeByPropertyObjectTrumpMergePolicyType];
            [parentContext setMergePolicy:mergePolicy];
        ];
        [threadContext setParentContext:self.mainManagedObjectContext];
        [threadDict setObject:threadContext forKey:kCGMManagedObjectContextKey];
    
    return threadContext;

【问题讨论】:

跟我遇到的问题一模一样,你有什么解决办法吗?我不明白为什么会出现这个问题,iOS 6 没有抱怨。在我的情况下,我看不出为什么会发生这种情况,因为我正在编辑的 ManagedObject 来自我正在保存的同一个 ManagedObjectContext,它为什么要抱怨合并错误? 【参考方案1】:

我只花了两天时间调试完全相同的错误。你的应用和我的区别在于我的应用只从主线程访问核心数据,所以合并错误更令人费解。

在我们的例子中,我把它缩小到我们有一个单向关系的事实 - A 有很多 B(建模为 NSSet),但 B 不知道它的 A。我们有一个修改 A 和a B,并且在我们保存这些更改时会导致合并错误。此代码在 iOS 5 和 6 上运行了很长时间,但在 iOS 7 上才开始失败。

确实,添加合并策略会使错误消失,但它也可能掩盖其他错误。在我们的例子中,我们宁愿看到这些错误,也不愿冒着数据库不一致的风险。

将关系更改为双向使错误消失。我们的应用程序不需要反向链接,但它们也没有伤害。 (令人高兴的是,更改这种关系作为轻量级迁移得到了正确处理 - 核心数据自动为我们填充了这些反向链接。)

【讨论】:

我遇到了完全相同的问题,这帮助我解决了它! NSMergeConflict 不是很清楚:/ 还记得在核心数据编辑器中设置“反向”字段。我们在应用程序中有双向关系,但开发人员忘记正确设置 Inverse,这导致了这种伪冲突。【参考方案2】:

根据苹果的文档

NSManagedObjectMergeError = 133020

此错误代码表示合并策略失败 - Core Data 无法完成合并。

您的代码中是否有任何合并策略?请尝试 NSMergeByPropertyObjectTrumpMergePolicy。

[self.context setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];

【讨论】:

【参考方案3】:

使用带有 Apple Watchkit 扩展的 Xcode 6.3.2,我在尝试进行多次更新和保存时遇到了同样的错误。 setMergePolicy 解决了这个问题,这里是 swift 代码:

context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy

确保将上述行放在 context.save 命令之前。

【讨论】:

使用 Swift,这完美地解决了基本相同的问题。谢谢! 我不会从来没有遇到过这个!甚至不想知道这行代码为我节省了多少小时的阅读和故障排除时间。【参考方案4】:

我不想在不了解导致 NSMergeConflict 首先的原因的情况下通过设置合并策略来掩盖潜在问题。

在我的情况下,我早些时候在我的代码中执行了NSBatchDeleteRequestNSBatchDeleteRequest 直接在持久存储协调器上执行,因此ManagedObjectContext 不知道删除并仍然持有对已删除对象的引用。当我后来引用其中一个对象并尝试保存上下文时,NSMergeConflict 被抛出。

执行删除后在我的moc 上调用reset() 解决了问题。

let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Tasks")
let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
try managedContext.execute(batchDeleteRequest)
managedContext.reset() 

【讨论】:

【参考方案5】:

我遇到了类似的错误,就我而言,锁定 NSPersistentStoreCoordinator 有效。

[context.persistentStoreCoordinator lock];
[context performBlockAndWait:^
   // do something
];
[context.persistentStoreCoordinator unlock]

我不知道它为什么起作用,但我怀疑 NSManagedObjectContext 的错误。 我希望这会有所帮助。

【讨论】:

【参考方案6】:

我在使用完整存储进行测试时得到了这个。因此,似乎任何类型的合并失败(在我的情况下,存储已满并且无法更新持久存储)都会产生这种情况。

【讨论】:

以上是关于iOS 7 上的 NS 合并冲突的主要内容,如果未能解决你的问题,请参考以下文章

QtOpengl 与 mac 上的 Opengl 框架冲突

Git 分支的创建、切换、合并以及解决冲突、删除

未更改的文件上的 Git 合并冲突

使用情节提要时iOS目标c中的合并冲突是啥

有没有办法通过比较分支来查看 GitHub 上的合并冲突?

Tfs / Azure DevOps 客户端库合并 Azure DevOps 分支上的冲突解决