使用prepareForReuse的正确方法是什么?

需要帮助了解如何在UIKit中使用prepareForReuse()。 文件说

您应该只重置与内容无关的单元格属性,例如,alpha,编辑和选择状态

但是重置个别属性属性如isHidden呢?

假设我的单元格有2个标签,我应该重置:

  1. label.text
  2. label.numberOfLines
  3. label.isHidden

我的tableView(_:cellForRowAt :)委托有条件逻辑来隐藏/显示每个单元格的标签。

根本不要使用prepareForReuse 。 它存在,但很少有情况下它是有用的,而你的不是其中之一。 在tableView(_:cellForRowAt:)完成所有工作。


引用Apple自己的文档 :

出于性能原因,您应该仅重置与内容无关的单元格属性,例如,alpha,编辑和选择状态。

例如,如果选择了一个单元格,您只需将其设置为未选中,如果您将背景颜色更改为某些内容,则只需将其重置为默认颜色即可。

tableView(_:cellForRowAt:)的表视图委托应该在重用单元格时重置所有内容

这意味着如果您尝试设置联系人列表的配置文件图像,则不应尝试在prepareforreuse设置图像,您应该在cellForRowAt正确设置图像,如果没有找到任何图像,则将其图像设置为nil或默认图像。 基本上, cellForRowAt应该控制预期/意外状态。

所以基本上不建议以下内容:

 override func prepareForReuse() { super.prepareForReuse() imageView?.image = nil } 

而是推荐以下内容:

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) cell.imageView?.image = image ?? defaultImage // unexpected situation is also handled. // We could also avoid coalescing the `nil` and just let it stay `nil` cell.label = yourText cell.numberOfLines = yourDesiredNumberOfLines return cell } 

此外,建议使用以下默认的非内容相关项:

 override func prepareForReuse() { super.prepareForReuse() isHidden = false isSelected = false isHighlighted = false } 

这是Apple建议的方式。 但说实话,我仍然认为将所有内容转移到cellForRowAt更容易,就像Matt所说的那样。 清洁代码很重要,但这可能无法帮助您实现这一目标。 但是,正如Connor说的那样,唯一需要的是,如果你需要取消正在加载的图像。 有关详情,请参阅此处

即做以下事情:

 override func prepareForReuse() { super.prepareForReuse() imageView.cancelImageRequest() // this should send a message to your download handler and have it cancelled. imageView.image = nil } 

如文档所述,您只需使用上述方法重置与内容无关的属性。 至于重置文本/行数….您可以在设置新值之前从tableView(_:cellForRowAt :)中执行此操作,如下所示:

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { cell.label.text = "" //reseting the text cell.label.text = "New value" return cell } 

要么

您可以采用更面向对象的方法并创建UITableViewCell的子类,并定义一个方法,即configureCell()来处理新出列单元格的所有重置和值设置。