【问题标题】:Cannot reorder an NSOrderedSet relationship in Core Data无法在 Core Data 中重新排序 NSOrderedSet 关系
【发布时间】:2012-03-18 03:36:44
【问题描述】:

有谁知道为什么我不能在 Core Data 的 NSOrderedSet 关系中保存对象顺序的更改?我已经知道将生成的函数用于 NSOrderedSet 关系的错误,因此我总是使用 keypath。下面是表格视图中两个函数的代码。

tableView:moveRowAtIndexPath:toIndexPath: 声称保存成功,但实际上并没有保存更改,这意味着如果我执行[tableView reloadData];,旧命令仍然存在。即使我退出应用程序并重新启动它,顺序也没有改变。我已经用多个 NSLogs 验证了这一点。第二个函数,tableView:commitEditingStyle:forRowAtIndexPath:,我用来删除一个 NSOrderedSet 条目,效果很好。

我的理论是,Core Data 在其内部表示中丢弃了来自 NSOrderedSet 关系的订单信息,因此由于对象保持不变,它认为它不需要保存任何东西。有没有人经历过这样的事情?如果是这样,您是否找到了解决方法?

-(void) tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath 
{

    NSManagedObjectContext *context= [self managedObjectContext];

    Playlist *playlist = (Playlist*) [context objectWithID:playlistID];


    [playlist willChangeValueForKey:@"tracks"];
    NSMutableOrderedSet *exchange = [playlist mutableOrderedSetValueForKey:@"tracks"];;

    NSInteger fromIndex = sourceIndexPath.row;
    NSInteger toIndex = destinationIndexPath.row;

    NSMutableArray *arrayOfTracks = [NSMutableArray arrayWithArray:[exchange array]];

    [arrayOfTracks exchangeObjectAtIndex:fromIndex withObjectAtIndex:toIndex];
    [[playlist mutableOrderedSetValueForKey:@"tracks"] removeAllObjects];


    [[playlist mutableOrderedSetValueForKey:@"tracks"] addObjectsFromArray:arrayOfTracks];
    playlist.md5Hash = nil;
    [playlist didChangeValueForKey:@"tracks"];

    NSError *savingError = nil;
    if ([context save:&savingError]){
        NSLog(@"Successfully saved the context for reorder"); 
    } else {
        NSLog(@"Failed to save the context. Error = %@", savingError); }

}


- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        NSManagedObjectContext *context= [self managedObjectContext];

        Playlist *playlist = (Playlist*) [context objectWithID:playlistID];

        Track *track = [self.tracksFRC objectAtIndexPath:indexPath];    


        NSMutableOrderedSet *exchange = [NSMutableOrderedSet orderedSetWithOrderedSet: playlist.tracks];


        [exchange removeObject:track];
        [track removeBelongingPlaylistObject:playlist];
        NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [playlist.tracks count])];

        [[playlist mutableOrderedSetValueForKey:@"tracks"] replaceObjectsAtIndexes:indexSet withObjects:[exchange array]];

        playlist.md5Hash = nil;

        NSError *savingError = nil;
        if ([context save:&savingError]){
            NSLog(@"Successfully saved the context for remove entry"); 
        } else {
            NSLog(@"Failed to save the context. Error = %@", savingError); }
    }
}

编辑:我能够通过调用[context save:&savingError] 两次来解决问题,一次删除记录,一次以新顺序重新插入记录。不过,这个修复不应该真的是必要的。

【问题讨论】:

  • 谢天谢地,这似乎在 iOS 6 中得到了修复。如果您需要洗牌大型对象树,这意味着性能会有很大的提升。
  • 你能发布编辑后的解决代码吗?我按照你说的做了,调用了两次 save,但还不足以让它工作......
  • 这在 iOS6 中修复了吗?有趣的是它仍然不适合我哈哈! :') 根据我的经验,Core Data 对编辑东西来说是一种痛苦!希望解决与此类似的问题!
  • 我在 iOS 10 中仍然遇到同样的问题。我认为您是对的,不认为它需要保存;我可以通过编辑完全不相关的 NSManagedObjects 来重新排序以保存。

标签: iphone objective-c uitableview core-data


【解决方案1】:

转换为数组的原因是什么? NSMutableOrderedSet已经支持exchangeObjectAtIndex:withObjectAtIndex:方法

我建议:

NSMutableOrderedSet *exchange = [playlist.tracks mutableCopy];

NSInteger fromIndex = sourceIndexPath.row;
NSInteger toIndex = destinationIndexPath.row;

[exchange exchangeObjectAtIndex:fromIndex withObjectAtIndex:toIndex];

playlist.tracks = exchange;

此外,您似乎在 Playlist 和 Track 之间存在多对多关系,因此您的 delete 方法之所以有效,是因为您调用了 [track removeBelongingPlaylistObject:playlist]; 方法中的所有其他内容都应该是多余的(除了保存上下文)。

【讨论】:

    【解决方案2】:

    将@ikuramedia 的代码转换为 swift 给出:

    var exchange: NSMutableOrderedSet = playlist.tracks.mutableCopy() as! NSMutableOrderedSet
    
    exchange.exchangeObjectAtIndex(fromIndexPath.row, withObjectAtIndex: toIndexPath.row)
    
    playlist.tracks = exchange
    

    如果有人需要它

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-07
      • 1970-01-01
      • 1970-01-01
      • 2013-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多