我在我的应用程序中使用 CollectionViewCells 和 TableViewCells,但对于这个示例,我将列出 TableViewCell 信息,因为它们都使用prepareForReuse
.
在牢房内,我有:
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var thumbnailImageView: UIImageView!
@IBOutlet weak var backgroundViewForPlayerLayer: UIView!
var data: MyData?
var currentTime: CMTime? // used to keep track of the current play time when the app is sent to the background
var playerItem: AVPlayerItem?
var player: AVPlayer?
var playerLayer: AVPlayerLayer?
当我获得单元格的表格数据时,我将数据提供给cellForRowAtIndexPath
. 我将它传递给data
单元格内的属性,并将单元格的缩略图和标题插座设置为 in awakeFromNib()
。我了解单元格是如何从场景中滚动出来然后重新使用的,所以我用它prepareForReuse
来清理单元格。
出于性能原因,您应该只重置与内容无关的单元格属性,例如 alpha、编辑和选择状态。重用单元格时,tableView(_:cellForRowAt:) 中的表视图委托应始终重置所有内容。
当需要清理单元格时,prepareForReuse
我通过反复试验发现清理标签文本的最佳方法是使用label.text = ""
而不是使用label.text = nil
上面的内容,显然 Apple 不想prepareToReuse
用于轻度清洁向上。但是,我已经阅读了关于 SO 的其他帖子,最好通过将 AVPlayerLayer 设置为nil
并将其从prepareForReuse
.
我有 2 个问题
- 如果不在里面
prepareForReuse
,那么我在哪里将currentTime
anddata
属性重置为nil
和imageView's image
tonil
?这是假设应用程序被发送到后台并且currentTime
属性设置为某个值。 - 如果我不能将标签的文本设置为 nil in
prepareForReuse
那么为什么最好将 AVPlayerLayer 设置为 nil inprepareForReuse
?
表视图单元格:
class MyCell: UITableViewCell{
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var thumbnailImageView: UIImageView!
var data: MyData?
var currentTime: CMTime?
var playerItem: AVPlayerItem?
var player: AVPlayer?
var playerLayer: AVPlayerLayer?
override func awakeFromNib() {
super.awakeFromNib()
NotificationCenter.default.addObserver(self, selector: #selector(appHasEnteredBackground), name: Notification.Name.UIApplicationWillResignActive, object: nil)
titleLabel.text = data.title!
thumbnailImageView.image = data.convertedUrlToImage() // url was converted to an image
configureAVPlayer() //AVPlayer is configured
}
override func prepareForReuse() {
super.prepareForReuse()
titleLabel.text = ""
player?.pause()
playerLayer?.player = nil
playerLayer?.removeFromSuperlayer()
// should I reset these 3 here or somewhere else?
data = nil
currentTime = nil
thumbnailImageView.image = nil
}
@objc func appHasEnteredBackground() {
currentTime = player.currentTime()
// pause the player...
}
}
cellForRowAtIndexPath:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCell
let data = tableData[indexPath.row]
cell.data = data
return cell
}