【问题标题】:NSMergeConflict on iOS7iOS 7 上的 NS 合并冲突
【发布时间】: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,它为什么要抱怨合并错误?

标签: ios objective-c core-data merge


【解决方案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】:

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

        【讨论】:

          猜你喜欢
          • 2013-11-09
          • 2015-10-11
          • 2018-07-10
          • 1970-01-01
          • 2021-06-27
          • 2019-10-18
          • 2016-12-09
          • 2018-03-03
          • 1970-01-01
          相关资源
          最近更新 更多