聊聊iOS中UITableView复用的那些事
theme: smartblue
持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情
今天跟大家聊聊在开发中我们所遇到的tableView复用的那些事,相信大家在使用tableView或者collectionView时,都会遇到cell复用导致UI错乱。在这篇文章中,我总结了一下几点。
UITableView
中的复用机制,想必大家应该都很清楚了。这里就先简单提一下:
在tableview
新建的时候,会新建一个复用池(reuse pool)。这个复用池可能是一个数组,或者是一个链表,保存着当前的cell
。pool中的对象的复用标识符就是reuseIdentifier
,标识着不同的种类的cell
。调用dequeueReusableCellWithIdentifier:
方法获取cell
。从pool中取出来的cell
都是tableview
展示的原型。无论之前有什么状态,全部都要设置一遍。
这里我们就不对tableview的复用机制过多的探讨,只讲讲平时开发容易忽略的复用的问题。
我列举了以下几种情况:
- 在cell中条件判断没有覆盖全场景
- 在cell中使用了延迟或者异步处理
- 在cell中UIImageView混用了网络图片和本地图片
在更新cell的条件判断没有覆盖全场景,只处理了某种条件下UI,其他的没有处理
if xx {
aLabel.isHidden = true
avatarView.isHidden = false
} else if xx {
aLabel.isHidden = false
avatarView.isHidden = true
} else {
aLabel.isHidden = true
}
在某些时候,cell可能会用来兼容很多情况,或者某一个的cell有很多状态,有时候因为疏忽导致没有处理全部的情况,常常出现了不该显示的UI元素显示出来了。
因为tableview中的cell在使用标识符之后就会被复用,那么我们就需要针对复用的cell去做格式化处理。比如每次刷新时,重制状态。这样就可以保证它的状态是正常的,而不是上一次遗留的。
在cell中的使用了延迟或者异步处理
if xx {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
avatarView.image = UIImage.init("123")
}
} else {
xxxx
}
有些时候,在cell中使用了延迟来处理某些逻辑。比如使用GCD或者异步回调来更新UI上的显示,可能会有tableView刷新时复用问题,所以在使用延迟时,需要格外注意延迟后的逻辑判断,在重新刷新时取消延迟处理或异步操作。
在cell中使用UIImageView加载网络图片和本地图片
if xx {
avatarView.image = UIImage.init("123")
} else {
avatarView.kf.setImage(with: url)
}
在cell中我们会经常使用到网络图片加载库来加载网络图片。在某些场景下,我们会将某个UIImageView
既用来加载网络图片,也用来加载本地图片。如果有使用场景下我们将一个控件用来处理本地、网络两种情况,那么需要注意,再给加载本地图片时取消网络图片的下载 sd_cancelCurrentImageLoad
,或者不要使用同一个控件来加载网络、本地图片;
原因:加载本地图片是同步进行的,而加载网络图片是异步的,有可能我们在刷新时,加载本地图片。但是上次加载的网络图片还未加载完,这时,如果等上次的网络图片加载完成后,那么这个图片就会造成复用了。
总结下来,容易被忽视的其实还是在cell中有异步的操作。
- LeetCode 初级算法之数组(上),看看你都学会了吗?
- LeetCode 初级算法之链表,看看你都学会了吗?
- LeetCode 初级算法之字符串(上),看看你都学会了吗?
- 纯代码布局,也可以一样的简洁
- UIStackView之一问一答
- 使用UIStackView来简化iOS的界面布局
- 夏天来了,iOS开发者们该如何减少App耗电?(上)
- 夏天来了,App开发者们如何看待手机发烫问题?
- 聊聊iOS中UITableView复用的那些事
- 曾经经典的微信打飞机游戏还有人记得吗?
- iOS 原生渲染与 Flutter 有什么区别 (上)
- 了解 Mach-O文件
- CocoaPods中podsepc文件设置详解
- iOS 原生渲染与 Flutter 有什么区别 (下)
- 简单了解 iOS CVPixelBuffer (上)
- 谈谈 iOS 包瘦身方案
- 播放器重构的探索之路
- 如何使用CocoaPods制作私有库
- iOS 组件化方案