使用 prepareForReuse 的正确方法是什么? [英] What is the correct way to use prepareForReuse?

查看:127
本文介绍了使用 prepareForReuse 的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

需要帮助理解如何在 UIKit 中使用 prepareForReuse().文档

Need help with understanding how to use prepareForReuse() in UIKit. The documentation says

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

you should only reset attributes of the cell that are not related to content, for example, alpha, editing, and selection state

但是如何重置诸如 isHidden 之类的单个属性?

but what about resetting individual property attributes such as isHidden?

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

Assuming my cell has 2 labels where should I reset:

  1. 标签文本
  2. label.numberOfLines
  3. label.isHidden

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

My tableView(_:cellForRowAt:) delegate has conditional logic to hide/show labels per cell.

推荐答案

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

tldr: use prepareForReuse to cancel out existing network calls that can can finish after downloading a different indexPath. For all other intents and purposes just use cellForRow(at:. This slightly against Apple docs. But that's how most devs do stuff. It's inconvenient to have cell configuration logic at both places...

Apple 文档说使用它来重置与内容无关的属性.然而,根据经验,在 cellForRow 内为内容做所有事情可能更容易,而不是.唯一真正有意义的时候是

Apple docs say use it to reset attributes not related to content. However based on experience it might easier to do just do everything inside cellForRow for content and not. The only time that it actually makes sense is to

Apple 的文档中引用 prepareForReuse代码>:

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

For performance reasons, you should only reset attributes of the cell that are not related to content, for example, alpha, editing, and selection state.

例如如果选择了一个单元格,您只需将其设置为未选择,如果您将背景颜色更改为某种颜色,那么您只需将其重置为默认颜色.

e.g. if a cell was selected, you just set it to unselected, if you changed the background color to something then you just reset it back to its default color.

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

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

This means if you were trying to set the profile images of your contact list you shouldn't attempt to nil images in prepareforreuse, you should correctly set your images in the cellForRowAt and if you didn't find any image then you set its image to nil or a default image. Basically the cellForRowAt should govern both the expected/unexpected status.

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

So basically the following is not suggested:

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
}

另外推荐默认的非内容相关项目,如下所示:

Additionally default non-content related items as below is recommended:

override func prepareForReuse() {
    super.prepareForReuse()
    isHidden = false
    isSelected = false
    isHighlighted = false
    // Remove Subviews Or Layers That Were Added Just For This Cell

}

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

This way you can safely assume when running cellForRowAt then each cell's layout is intact and you just have to worry about the content.

这是苹果推荐的方式.但老实说,我仍然认为像 Matt 所说的那样将所有内容转储到 cellForRowAt 中更容易.干净的代码很重要,但这可能无法真正帮助您实现这一目标.但正如康纳所说唯一一次必要的是,如果您需要取消正在加载的图像.如需更多信息,请参见此处

This is the Apple's suggested way. But to be honest, I still think it's easier to dump everything inside cellForRowAt just like Matt said. Clean code is important, but this may not really help you achieve that. But as Connor said the only time it's necessary is, if you need to cancel an image that is loading. For more see here

即做类似的事情:

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


另外在使用 RxSwift 的特殊情况下:请参阅此处这里

这篇关于使用 prepareForReuse 的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆