前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【iOS 开发】tableView updates 对比 reloadData

【iOS 开发】tableView updates 对比 reloadData

作者头像
KyXu
发布2019-04-11 16:52:15
1.8K0
发布2019-04-11 16:52:15
举报
文章被收录于专栏:KyXu

Paste_Image.png

如图有一个 TableView,每行显示这一行是第几行,现在我希望每按一次 update 按钮,就动态地在下方加两行。那么简单粗暴的做法是 ,更改数据源,然后刷新一下列表:

代码语言:javascript
复制
// tableData = ["0", "1", "2", "3"]
@IBAction func update(_ sender: AnyObject) {
    tableData.append("\(tableData.count)")
    tableData.append("\(tableData.count)")
    tableView.reloadData()
}

用膝盖想也知道,这会使得前四行没有被改动的地方也被刷新一遍,带来了不必要的性能损耗。 好一点的做法是下面这样的:

代码语言:javascript
复制
// tableData = ["0", "1", "2", "3"]
@IBAction func update(_ sender: AnyObject) {
    tableData.append("\(tableData.count)")
    tableData.append("\(tableData.count)")
    tableView.beginUpdates()
    let indexPaths = [IndexPath(row: tableData.count-2, section: 0), IndexPath(row: tableData.count-1, section: 0)]
    tableView.insertRows(at: indexPaths, with: UITableViewRowAnimation.automatic)
    tableView.endUpdates()
}

与上面相比,这样做使得 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 方法被少调用了四次。

这里 beginUpdatesendUpdates 方法的作用是,将这两条语句之间的对 tableView 的 insert/delete 操作聚合起来,然后同时更新 UI。鉴于我这里只进行了一次 insert 操作,把这两条语句去掉也没事,但是出于规范还是应该写上,因为假如习惯不写,下面这样的代码会运行时崩溃:

代码语言:javascript
复制
@IBAction func update(_ sender: AnyObject) {
    tableData.append("\(tableData.count)")
    tableData.append("\(tableData.count)")
    //        tableView.beginUpdates()
    tableView.insertRows(at: [IndexPath(row: tableData.count-2, section: 0)], with: UITableViewRowAnimation.automatic)
    tableView.insertRows(at: [IndexPath(row: tableData.count-1, section: 0)], with: UITableViewRowAnimation.automatic)
    //        tableView.endUpdates()
}

因为第一次 insert 之后,当前 row 的总数量在 UI 上试图 4 变成 5,然而数据源是 6,它会检查使用者对 tableView 的 UI 操作,最后是不是和 numberOfRows 方法获取的值相对应。

总结

numberOfRows 方法调用: 都只调用一次 numberOfRows 方法

cellForRow 方法调用次数: reloadData 会为当前显示的所有cell调用这个方法,updates 只会为新增的cell调用这个方法 cellForRow 方法调用时间: reloadData 会在 numberOfRows 方法调用后的某一时间异步调用 cellForRow 方法,updates 会在 numberOfRows 方法调用后马上调用 cellForRow 方法

reloadData 方法缺陷: 带来额外的不必要开销,缺乏动画 updates 方法缺陷:deleteRows 不会调用 cellForRow 方法,可能导致显示结果与数据源不一致;需要手动保证 insertRows、deleteRows 之后,row 的数量与 numberOfRows 的结果一致,否则会运行时崩溃


部分文章中没有写,总结提到了的部分放在完整 demo 里面了:demo Github 地址

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016.10.11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档