更新 UITableView 使用的数据模型数组的正确方法 [关闭]

Posted

技术标签:

【中文标题】更新 UITableView 使用的数据模型数组的正确方法 [关闭]【英文标题】:The proper way to update data-model array used by UITableView [closed] 【发布时间】:2017-05-25 11:36:14 【问题描述】:

我猜我们应该倾向于为 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 最终删除了一个元素。就是这样...但是像后一个示例中那样执行操作,可以让我拥有不可变的数据模型数组。

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

【问题讨论】:

【参考方案1】:

我希望有一个可变数组,但将其设为私有。然后,如果另一个类需要更改数组,您可以提供add() 方法和delete() 方法。两者都将负责更新数组和表格视图。

【讨论】:

它实际上已经是私有的了......我更担心如果我保持它可变,在哪些情况下可能会发生一些混乱...... 如果您更改数组,无论可变性如何,表视图都必须随之更新,否则您将看到错误数据并可能崩溃(滚动到末尾时出现索引越界错误,例如)【参考方案2】:

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

现在,您是对的:您可以通过更改支持数据来搞砸您的表格视图。但无论特定集合的可变性如何,都会发生这种情况。您的不可变数组 sn-p 执行相同的操作:在您使用 deleteRowsAtIndexPaths:animated 通知它之前,表格视图不知道有任何更改。在数据源更新时重新加载表格视图是必要的,无论您的数据源在内部做什么。

【讨论】:

好的,我现在明白你们在说什么了。不过,我认为在上述情况下不需要reloadData,因为deleteRowsAtIndexPaths 会自动更新tableview,对吧?我的意思是,我改变data-model数组,然后我调用deleteRowsAtIndexPaths,tableview会自动更新而不需要发送reloadData? 是的,抱歉,您说的完全正确。我没有仔细阅读您的代码。【参考方案3】:

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 负责处理。你只需要更新你的数据源

【讨论】:

以上是关于更新 UITableView 使用的数据模型数组的正确方法 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

如何从属于 UITableView 中的模型数组对象的数组中向 tableView 显示数据?

同步更新 UITableView 的模式?

基于数组更新 UITableView

无法根据来自 UIPickerView 的选择器更新 UITableView 数据

如何正确修改 UITableView 数据源数组

iOS小技能:1. 什么是UITableView? 2. UITableView如何展示数据