核心数据错误 133020:在保存中合并问题:

Posted

技术标签:

【中文标题】核心数据错误 133020:在保存中合并问题:【英文标题】:Core Data error 133020: problems merging in a save: 【发布时间】:2012-03-27 13:57:14 【问题描述】:

首先,我想说我没有使用线程或多个上下文,并且我已经阅读并研究了我在 SO 上可以找到的所有相关答案。我有一个项目,我已将 Core Data 添加到其中,并且发现无法找到有害的错误。我每次都可以使用以下代码重现该错误。

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath   

    OT_Track *track;

    track = [[self.tracksArray objectAtIndex: fromIndexPath.row] retain];
    [self.tracksArray removeObjectAtIndex: fromIndexPath.row];
    [self.tracksArray insertObject:track atIndex: toIndexPath.row];
    [track release];

    for( int n = 0; n < [self.tracksArray count]; n++ ) 
        track = [self.tracksArray objectAtIndex:n];
        track.positionInPlaylist = [NSNumber numberWithInteger:n];
    

    if( [self.managedObjectContext hasChanges] && ![self.managedObjectContext save:&error] )    
        NSLog(@"Unable to Save Core Data Context");
    

self.tracksArray 是从 viewWillAppear 中执行的提取填充的 NSMutableArray。 OT_Track 是在我的妈妈中定义的实体,它有一个名为 positionInPlaylist 的字段(定义为 Integer32)。 positionInPlaylist 将 OT_Track 的位置存储在 OT_Playlist 中,允许用户重新排序播放列表中的项目。

我将非常感谢您在这方面的任何帮助,因为它让我发疯了!

我得到的错误是..

**************  Error  ********    The operation couldn’t be completed. (Cocoa error 133020.)
2012-03-27 13:03:32.578 OneTrack[7693:707]   detailedErrors: (null)
2012-03-27 13:03:32.587 OneTrack[7693:707]   
    conflictList =     (
        "NSMergeConflict (0x4018590) for NSManagedObject (0x40d7e60) with objectID '0x40debd0 <x-coredata://3A300D46-4B20-46DA-A82E-0785BFFAFF14/OT_Track/p2642>' with oldVersion = 1 and newVersion = 2 and old cached row = \n    artistName = \"Ladysmith Black Mambazo\";\n    disabled = 0;\n    persistentID = \"-2511068126837362989\";\n    playing = 0;\n    playlist = \"0x401a7a0 <x-coredata://3A300D46-4B20-46DA-A82E-0785BFFAFF14/OT_Playlist/p62>\";\n    podcast = 0;\n    positionInPlaylist = 0;\n    trackAutoplay = 0;\n    trackEndTime = \"222.563\";\n    trackLoop = 0;\n    trackMaxTime = \"222.563\";\n    trackName = Abezizwe;\n    trackPredelay = 0;\n    trackSignature = 2;\n    trackStartTime = 0;\n    trackTempo = 120;\n    trackVolume = 1;\n and new database row = \n    artistName = \"Ladysmith Black Mambazo\";\n    disabled = 0;\n    persistentID = \"-2511068126837362989\";\n    playing = 0;\n    playlist = \"0x40188b0 <x-coredata://3A300D46-4B20-46DA-A82E-0785BFFAFF14/OT_Playlist/p62>\";\n    podcast = 0;\n    positionInPlaylist = 2;\n    trackAutoplay = 0;\n    trackEndTime = \"222.563\";\n    trackLoop = 0;\n    trackMaxTime = \"222.563\";\n    trackName = Abezizwe;\n    trackPredelay = 0;\n    trackSignature = 2;\n    trackStartTime = 0;\n    trackTempo = 120;\n    trackVolume = 1;\n",
        "NSMergeConflict (0x4018610) for NSManagedObject (0x40dc990) with objectID '0x40deed0 <x-coredata://3A300D46-4B20-46DA-A82E-0785BFFAFF14/OT_Track/p2645>' with oldVersion = 1 and newVersion = 2 and old cached row = \n    artistName = \"Warren Zevon\";\n    disabled = 0;\n    persistentID = \"-2511068126837362101\";\n    playing = 0;\n    playlist = \"0x401ac40 <x-coredata://3A300D46-4B20-46DA-A82E-0785BFFAFF14/OT_Playlist/p62>\";\n    podcast = 0;\n    positionInPlaylist = 3;\n    trackAutoplay = 0;\n    trackEndTime = \"223.686\";\n    trackLoop = 0;\n    trackMaxTime = \"223.686\";\n    trackName = \"Accidentally Like A Martyr\";\n    trackPredelay = 0;\n    trackSignature = 2;\n    trackStartTime = 0;\n    trackTempo = 120;\n    trackVolume = 1;\n and new database row = \n    artistName = \"Warren Zevon\";\n    disabled = 0;\n    persistentID = \"-2511068126837362101\";\n    playing = 0;\n    playlist = \"0x4018420 <x-coredata://3A300D46-4B20-46DA-A82E-0785BFFAFF14/OT_Playlist/p62>\";\n    podcast = 0;\n    positionInPlaylist = 3;\n    trackAutoplay = 0;\n    trackEndTime = \"223.686\";\n    trackLoop = 0;\n    trackMaxTime = \"223.686\";\n    trackName = \"Accidentally Like A Martyr\";\n    trackPredelay = 0;\n    trackSignature = 2;\n    trackStartTime = 0;\n    trackTempo = 120;\n    trackVolume = 1;\n"
    );

self.tracksArray 由 viewWillAppear 调用的以下方法填充...

- (BOOL) populateTracksArray    

    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"OT_Track" inManagedObjectContext:self.managedObjectContext];
    [request setEntity:entity];

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"positionInPlaylist" ascending:YES];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
    [request setSortDescriptors:sortDescriptors];
    NSPredicate *fetchPredicate = [NSPredicate predicateWithFormat:@"playlist == %@", currentUserPlaylist];
    [request setPredicate:fetchPredicate];
    [sortDescriptors release];
    [sortDescriptor release];

    NSError *error = nil;
    NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
    if (mutableFetchResults == nil)  // Handle the error.
        return false;
    

    [self setTracksArray:mutableFetchResults];
    [mutableFetchResults release];
    [request release];

    return true;

【问题讨论】:

【参考方案1】:

您是否尝试过在托管对象上下文中设置合并策略?

默认是NSErrorMergePolicy,它只会抛出错误。你的other options are here。

我会推荐这个:

[self.managedObjectContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];

刚刚注意到可能会导致您的交换曲目代码出现问题。

代替

OT_Track *track;

track = [[self.tracksArray objectAtIndex: fromIndexPath.row] retain];
[self.tracksArray removeObjectAtIndex: fromIndexPath.row];
[self.tracksArray insertObject:track atIndex: toIndexPath.row];
[track release];

试试this blog post的代码sn-p。

我认为您的曲目交换代码可能会在交换过程中混淆索引。

【讨论】:

感谢院长的建议。我用 NSMergeByPropertyObjectTrumpMergePolicy 尝试了上述方法,但事情在保存时冻结了:所以我尝试了 NSOverwriteMergePolicy,事情又冻结了。我不确定如何分析控制台输出刚停止时冻结时发生的情况。我将补充一点,我可以在其他编辑后保存上下文(例如删除曲目或播放列表)。 我发现了一些可能会导致您的交换曲目代码出现问题的问题 - 我添加了一个指向博客文章的链接,该文章的解决方案可能会有所帮助。 按照博客文章中的建议创建了类别,但没有效果,如果我实施 mergePolicy,我仍然会遇到合并错误或冻结。我非常感谢您在这方面的帮助。 我尝试使用 NSRollbackMergePolicy 的 mergePolicy,它可以工作,但显然不会更新上下文。我还尝试设置另一个字段 track.trackAutoplay,它是一个 BOOL,以防万一整数 32 出现问题但也有同样的问题。 这很奇怪,但看起来如果我将 save: 放在循环中,那么合并错误就会消失!你知道为什么会这样吗?【参考方案2】:

我仍然不确定是什么原因造成的,但问题再次出现,我通过确保使用 performSelectorOnMainThread 在主线程上执行任何引用核心数据的方法来解决它。

【讨论】:

以上是关于核心数据错误 133020:在保存中合并问题:的主要内容,如果未能解决你的问题,请参考以下文章

iOS 7 上的 NS 合并冲突

核心数据合并政策

核心数据错误与异常第 3 部分

合并冲突核心数据

NSManagedObject 保存在核心数据中但属性错误

核心数据关系在删除后导致保存错误