UITableView
首先加载能够覆盖一屏幕的 UITableViewCell
(具体个数要根据每个 cell 的高度而定)。
然后当我们往上滑动时(往下滑动同理),需要一个新的 cell 放置在列表的下方。此时,我们不去生成新的 cell 而是先从 UITableView 的复用池里去获取,该池存放了已经生成的、能够复用的 cell ,如果该池为空,才会主动创建一个新的 cell 。
复用池的 cell 是这样被添加至该池的:当我们向上滑动视图时(向下滑动同理),位于最顶部的 cell 会相应地往上运动,直至消失在屏幕上。当其消失在视图中时,会被添加至当前 UITableView
的复用池。
因此,在渲染海量数据的列表时,并不需要很多 cell ,这得益于 UITableView
的复用机制。
当我们没有显式地设置 cell 的样式和内容时,它会继续沿用回收前的样式和内容设置。
例如
当我将tableView下滑一段,再滑回来时,出现如下情况:
通过输出cell的description观察地址后发现,cell0重用了cell11的地址。
所以出现了内容还存在的情况,验证了很多个数据后发现复用池的数量比当前显示的cell数量略多一些。
原始代码:
TableViewController.swift
//
// TableVC.swift
// test123
//
//
import UIKit
class TableVC: UITableViewController {
let dataSource = ["", "", "", "", "test", "test", "test", "test", "test", "test", "test", "test", "test"]
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(TableViewCell.self, forCellReuseIdentifier: TableViewCell.reuseIdentifier)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: TableViewCell.reuseIdentifier) as? TableViewCell
// let cell = TableViewCell(style: .default, reuseIdentifier: nil)
print("---------cell\(indexPath.row)被添加到视图中了")
cell!.cellOfIndex = indexPath.row
cell!.data = dataSource[indexPath.row % dataSource.count]
print(cell!.description)
return cell!
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 100
}
}
TableViewCell.swift
//
// TableViewCell.swift
// test123
//
//
import UIKit
class TableViewCell: UITableViewCell {
static let reuseIdentifier = "TableViewCell"
let indicateLabel = UILabel()
let dataLabel = UILabel()
var cellOfIndex: Int!
var data: String! {
didSet{
display()
}
}
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
indicateLabel.frame = CGRect(x: 0, y: 30, width: 150, height: 40)
dataLabel.frame = CGRect(x: 150, y: 30, width: 100, height: 40)
contentView.addSubview(indicateLabel)
contentView.addSubview(dataLabel)
}
required init?(coder: NSCoder) {
fatalError()
}
func display(){
if data == "" {
indicateLabel.text = "cell\(cellOfIndex!)暂无数据"
//显示设置
// dataLabel.text = ""
}else{
indicateLabel.text = "cell\(cellOfIndex!)有数据"
dataLabel.text = data
}
}
}
1、取消复用机制,直接静态生成(资源消耗太多)
2、为每个cell根据indexPath设置唯一标识符(同上)
3、直接显式赋值呗(最easy)