更新 UITableView 使用的数据模型数组的正确方法

The proper way to update data-model array used by UITableView

我猜我们应该倾向于为 UITableView 使用的数据模型数组使用不可变数组。关于这个的阅读在互联网上非常不同。我会说这可以防止在 tableview 显示数据时修改数组。例如,如果发生上述情况,numberOfRowsInSection: 方法可能会出现问题,对吧(即使我知道这在理论上是可能的,但我仍然无法真正想到这种情况如何在现实世界中发生)?

现在,在 commitEditingStyle:forRowAtIndexPath: 方法中,我正在这样做(messagesArray 是可变的):

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
 if (editingStyle == UITableViewCellEditingStyleDelete) {
    Message *message = messageArray[indexPath.row];
    [messagesArray removeObject:message];
    [self.messageTable deleteRowsAtIndexPaths:[NSArray arrayWithObject: indexPath] withRowAnimation:UITableViewRowAnimationFade];
}

而不是(messagesArray 不可变):

 NSMutableArray *temp = [NSMutableArray arrayWithArray:messagesArray];
 [temp  removeObject:message];
 messagesArray = [NSArray arrayWithArray:temp];

如果 messageArray 是不可变的,则后一个代码是我必须做的。

现在我有两个问题...IMO(如果我错了请纠正我),在上面的方法中以两种方式从数组中删除一个对象具有相同的效果。 messagesArray 最终删除了一个元素。就是这样......但是像后面的例子那样做,让我拥有不可变的数据模型数组。

有人可以评论在删除单元格后更新数据模型数组的实际首选方式(或者我可以说正确的方式吗?)?

我更愿意有一个 mutable 数组,但将其设为私有。然后,如果另一个 class 需要更改数组,您可以提供一个 add() 方法和一个 delete() 方法。两者都将负责更新数组和 table 视图。

从 table 视图的角度来看,您的数据源使用什么结构来组织数据并不重要。 table 视图不直接访问该结构。它在需要时向数据源询问它需要的部分。

现在,您是对的:您可以通过更改支持数据来搞砸您的 table 视图。但无论特定集合的可变性如何,都会发生这种情况。你的 immutable 数组片段做同样的事情:table 视图不知道有什么改变,直到你用 deleteRowsAtIndexPaths:animated通知 它。在数据源更新时重新加载 table 视图是 必不可少的,无论您的数据源在内部做什么。

Swift 3 版本:

func tableView(_ tableView: UITableView, commit editingStyle: 

UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {

        //1. remove data from model
        dataSource.remove(at: indexPath.row)

        //2. remove row from view
        tableView.deleteRows(at: [indexPath as IndexPath], with: .fade)
    }
}

是的!实现滑动删除时不需要重新加载数据! UITableView 处理它。你只需要更新你的数据源