dequeueReusableCell(withIdentifier标识符:字符串,对于indexPath:IndexPath)在每次调用时返回2个不同的单元格

时间:2019-05-06 11:22:17

标签: ios swift uitableview reuseidentifier

不知道您是否遇到过这种情况,我使用该功能

func tableView(_ tableView: UITableView, 
     cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
  let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: ReusableCell.self), for: indexPath) as! ReusableCell 
  cell.reloadAction = { 
    tableView.reloadRows(at: [IndexPath(row: 0, section: 0)], with: .none) 
  } 
  return cell 
}

检索可重复使用的单元格。但是现在每次我重新加载该单元格时,都再次调用此函数,并且每次调用都返回2个不同的单元格。 我在情节提要板上绘制了单元格,所以我无法在代码中多次注册单元格。 如果您遇到过这种情况,请帮助我,我很困惑:( 非常感谢。

2 个答案:

答案 0 :(得分:0)

您的标识符名称似乎很奇怪(您不需要指定其类型(字符串):是在界面构建器窗格中设置的标识符吗? 我建议您检查标识符名称,并尝试使用以下代码:withIdentifier:“ myCell”。希望这会有所帮助。

答案 1 :(得分:0)

对于给定的indexPath,dequeueReusableCell函数未返回相同的单元实例。它返回先前分配的当前不用于内存效率的单元实例,如果没有可用的单元实例,则返回一个新的单元实例。

触发单元格的重新加载时,它不会重新加载相同的实例,而是跳转到相同的cellForRowAt函数中,该函数将返回重用的单元格或新单元格。

您可以自己缓存所有单元并在请求新单元之前对其进行查找。内存使用效率不高,但是IndexPath始终具有相同的单元实例。在某些情况下,使用自己的缓存很有意义。对于数据模型中的许多条目(比如说包含10000首歌曲的列表),这是回收未使用(也就是未显示)单元的最佳方法。

然后如何更新单元格? 在UITableView中重新加载单元格的最佳实践取决于需要重新加载的事件的来源。这两个事件与UI(用户)相关或与数据模型相关。

UI /用户: 您要从单元中进行重新加载行为吗?然后让单元查询数据模型并更新其内容。单元格可以将其IndexPath作为属性,以及对数据模型的弱引用,并向数据模型询问最新数据。或者,您询问UITableViewDataSource单元属于哪个IndexPath,以找出与之相关的数据。

数据模型: 为什么要计算没有更新的地方?数据更改时,更常见且类似于Apple的方式是进行更新。在这种情况下,数据模型会知道它已更改并触发更新。大多数情况下使用的是reloadData(),但您也可以在单独的线程中更新所有可见的单元格。对于每个单元格,您可以使用UITableViewDataSource告诉您它具有什么IndexPath,然后确定该单元格是否需要更新。或者,每个单元格都知道其IndexPath并自行决定是否要更新此单元格的数据。

您可能会注意到,有许多方法可以更新单元格。我不知道哪种方法最适合您的应用程序需求,但是我认为您现在有一些灵感来解决它。 干杯

相关问题