iOS7上的NSMergeConflict

use*_*695 9 merge core-data objective-c ios

我更新了我的应用程序以支持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}"
Run Code Online (Sandbox Code Playgroud)

在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;
}
Run Code Online (Sandbox Code Playgroud)

}

scl*_*age 16

我花了两天时间调试完全相同的错误.你的应用程序与我的应用程序之间的区别在于我的应用程序只访问主线程中的核心数据,因此合并错误更令人费解.

在我们的例子中,我将其缩小到我们有一个单向关系的事实 - A有很多B(建模为NSSet),但B不知道它A.我们有一个修改A和B的方法,当我们去保存这些更改时会导致合并错误.这段代码在iOS 5和6上都运行良好,并且在iOS 7上才开始失败.

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

将关系更改为双向会导致错误消失.我们的应用程序不需要反向链接,但它们也没有受到伤害.(幸运的是,改变这种关系作为轻量级迁移正确处理 - 核心数据自动填入我们的那些反向链接.)


Min*_*ias 15

根据苹果的文档

NSManagedObjectMergeError = 133020

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

您的代码中是否有合并政策?请尝试NSMergeByPropertyObjectTrumpMergePolicy.

[self.context setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
Run Code Online (Sandbox Code Playgroud)


ffa*_*bri 6

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

context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
Run Code Online (Sandbox Code Playgroud)

确保将上面的行放在context.save命令之前.