核心数据错误 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:在保存中合并问题:的主要内容,如果未能解决你的问题,请参考以下文章