First off I want to say that I am not using threads or multiple contexts and I have read and worked from every related answer I could find on SO. I have a project which I have added Core Data to and am finding it impossible to find a pernicious bug. I can reproduce the bug every time using the following code.
- (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 is an NSMutableArray populated from a fetch performed in viewWillAppear. OT_Track is an Entity defined in my momd which has a field called positionInPlaylist (defined as Integer32). positionInPlaylist stores the position of an OT_Track in an OT_Playlist which allows the user to re-order items in the playlist.
I would be so grateful for any assistance on this as it's driving me nuts!
the error I am getting is..
************** 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 is populated by the following method called from 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;
}