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

2024-04-16

需要帮助了解如何在 UIKit 中使用prepareForReuse()。 这文档 https://developer.apple.com/reference/uikit/uitableviewcell/1623223-prepareforreuse says

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

但是重置单个属性(例如 isHidden)怎么样?

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

  1. 标签.文本
  2. 标签.行数
  3. 标签被隐藏

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


总而言之:使用prepareForReuse取消可以在下载不同的索引路径后完成的现有网络调用。对于所有其他意图和目的,只需使用cellForRow(at:。这有点违背苹果文档。但这就是大多数开发人员做事的方式。在两个地方都有单元配置逻辑很不方便......


苹果文档说用它来重置属性not相关content。然而,根据经验,只做里面的所有事情可能会更容易cellForRow对于内容和不。唯一真正有意义的时候是

引用自苹果的文档 https://developer.apple.com/documentation/uikit/uitableviewcell/1623223-prepareforreuse for prepareForReuse:

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

例如如果选择了一个单元格,您只需将其设置为未选择,如果您将背景颜色更改为某种颜色,则只需将其重置回原来的颜色default color.

表视图的委托在tableView(_:cellForRowAt:) 应该 总是重置所有内容重复使用电池时。

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

所以基本上以下是not建议:

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
    // Remove Subviews Or Layers That Were Added Just For This Cell

}

这样你就可以在运行时安全地假设cellForRowAt那么每个单元格的布局都是完整的,您只需担心内容即可。

这是Apple建议的方式。但说实话,我还是觉得把所有东西都倒进去比较容易cellForRowAt就像马特说的那样。干净的代码很重要,但这可能并不能真正帮助您实现这一目标。但作为康纳说 https://stackoverflow.com/questions/40773208/what-is-the-correct-way-to-use-prepareforreuse/47514477#comment81985130_40773421唯一需要的时候是当您需要取消正在加载的图像时。更多请参见here https://medium.com/ios-seminar/why-we-use-dequeuereusablecellwithidentifier-ce7fd97cde8e

即做类似的事情:

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

另外,在使用 RxSwift 的特殊情况下: 看here https://stackoverflow.com/questions/41648830/rxswift-textfield-variable-binding-in-tableview/41675651#41675651 or here https://medium.com/gett-engineering/disposing-rxswifts-memory-leaks-6ceb73162170

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用prepareForReuse的正确方法是什么? 的相关文章

随机推荐