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

首先,我想说我没有使用线程或多个上下文,而且我已经从所有可以find的相关答案中阅读和工作。 我有一个项目,我已经添加了核心数据,我发现不可能find一个有害的错误。 我可以每次使用下面的代码重现错误。

- (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中,该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; } 

你有没有尝试设置您的托pipe对象上下文的合并策略?

默认是NSErrorMergePolicy ,它只会抛出错误。 你的其他选项在这里 。

我build议这个:

 [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]; 

尝试从这个博客文章的代码片段。

我认为你的跟踪交换代码可能会让索引在交换过程中感到困惑。

我仍然不确定是什么造成了这个问题,但问题重演,我解决了这个问题,确保引用核心数据的任何方法都是在主线程上使用performSelectorOnMainThread执行的。