iOS7上的NSMergeConflict

我已经更新了我的应用程序,以支持iOS 7,并已经面临在我的[context save];屏幕之一的问题[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; } 

}

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

在我们的例子中,我缩小了事实,我们有一个单向关系 – A有很多Bs(模拟为NSSet),但是B不知道它的A.我们有一个方法修改了A和B,当我们去保存这些更改时会导致合并错误。 这段代码在iOS 5和iOS 6上都很好地工作了很长时间,并且只在iOS 7上开始失败。

确实,添加合并策略会使错误消失,但也可能会掩盖其他错误。 在我们的情况下,我们宁愿看到那些错误,而不是具有不一致DB的风险。

改变双向关系使错误消失。 我们的应用程序没有必要使用反向链接,但它们也没有受到任何伤害。 (令人高兴的是,改变这种关系作为一种轻量级迁移被正确处理 – 核心数据自动填充在我们的这些后链接中。)

根据苹果的文件

NSManagedObjectMergeError = 133020

此错误代码表示合并策略失败 – 核心数据无法完成合并。

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

 [self.context setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy]; 

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

 context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy 

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

我不想通过设置合并策略来掩盖潜在的问题,而不理解首先导致NSMergeConflict

在我的情况下,我曾经在我的代码中执行过一个NSBatchDeleteRequestNSBatchDeleteRequest直接在持久存储协调器上执行,因此NSBatchDeleteRequest不知道删除操作,仍然保留对已删除对象的引用。 当我稍后引用这些对象之一并尝试保存上下文时,引发了NSMergeConflict

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

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

我有类似的错误,在我的情况下,lockingNSPersistentStoreCoordinator工作。

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

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

我用完整的存储testing时得到了这个。 所以看起来,任何types的合并失败(在我的情况下,存储已满,持久性存储无法更新)将产生这种情况。