详细整理iOS中UITableView的性能优化
发布时间 - 2026-01-11 00:17:41 点击率:次一、介绍

iOS开发中,UITableView可能是平时我们打交道最多的UI控件之一,其重要性不言而喻。Android也是如此,Android中的ListView和UITableView是相同功能的一个控件,但是iOS的UITableView更为强大一点,原因就不说了,如果你学过Android就知道iOS中的UITableView使用起来是非常简单的,这也是峰哥喜欢iOS胜过Android的原因之一。今天研究的内容就是UITableView的优化。
开始之前,你能说出几种UITableView的可优化项?cell复用(Android中经常称为ListView的重用,其实重用复用都是一个意思,由于峰哥之前做过Android的原因,有时候我经常说“重用”,后面万一说“重用”大家知道是“复用”的意思就行了)!除了cell重用呢?
二、UITableView的性能优化
1、cell复用
复用很简单,这或许是所有iOS开发者最为熟知的一个优化内容,如下代码:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *Identifier = @"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
}
return cell;
}
但是,这样重用就完美了吗?
我们经常在注意cellForRowAtIndexPath:中为每一个cell绑定数据,实际上在调用cellForRowAtIndexPath:的时候cell还没有被显示出来,为了提高效率我们应该把数据绑定的操作放在cell显示出来后再执行,可以在tableView:willDisplayCell:forRowAtIndexPath:(以后简称willDisplayCell)方法中绑定数据。
注意willDisplayCell在cell 在tableview展示之前就会调用,此时cell实例已经生成,所以不能更改cell的结构,只能是改动cell上的UI的一些属性(例如label的内容等)。
2、cell高度的计算
这边我们分为两种cell,一种是定高的cell,另外一种是动态高度的cell。
(1)定高的cell,应该采用如下方式:
self.tableView.rowHeight = 88;
这个方法指定了所有cell高度都是88的tableview,rowHeight默认的值是44,所以一个空的TableView会显示成这个样子。对于定高cell,直接采用上面方式给定高度,不需要实现tableView:heightForRowAtIndexPath:以节省不必要的计算和开销。
(2)动态高度的cell
我们需要实现它的代理,来给出高度:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
// return xxx
}
这个代理方法实现后,上面的rowHeight的设置将会变成无效。在这个方法中,我们需要提高cell高度的计算效率,来节省时间。
自从iOS8之后有了self-sizing cell的概念,cell可以自己算出高度,使用self-sizing cell需要满足以下三个条件:
(1)使用Autolayout进行UI布局约束(要求cell.contentView的四条边都与内部元素有约束关系)。
(2)指定TableView的estimatedRowHeight属性的默认值。
(3)指定TableView的rowHeight属性为UITableViewAutomaticDimension。
- (void)viewDidload {
self.myTableView.estimatedRowHeight = 44.0;
self.myTableView.rowHeight = UITableViewAutomaticDimension;
}
除了提高cell高度的计算效率之外,对于已经计算出的高度,我们需要进行缓存,对于已经计算过的高度,没有必要进行计算第二次。
3、渲染
为了保证TableView的流畅,当快速滑动的时候,cell必须被快速的渲染出来。所以cell渲染的速度必须快。如何提高cell的渲染速度呢?
(1)当有图像时,预渲染图像,在bitmap context先将其画一遍,导出成UIImage对象,然后再绘制到屏幕,这会大大提高渲染速度。具体内容可以自行查找“利用预渲染加速显示iOS图像”相关资料。
(2)渲染最好时的操作之一就是混合(blending)了,所以我们不要使用透明背景,将cell的opaque值设为Yes,背景色不要使用clearColor,尽量不要使用阴影渐变等
(3)由于混合操作是使用GPU来执行,我们可以用CPU来渲染,这样混合操作就不再执行。可以在UIView的drawRect方法中自定义绘制。
4、减少视图的数目
我们在cell上添加系统控件的时候,实际上系统都会调用底层的接口进行绘制,大量添加控件时,会消耗很大的资源并且也会影响渲染的性能。当使用默认的UITableViewCell并且在它的ContentView上面添加控件时会相当消耗性能。所以目前最佳的方法还是继承UITableViewCell,并重写drawRect方法。
5、减少多余的绘制操作
在实现drawRect方法的时候,它的参数rect就是我们需要绘制的区域,在rect范围之外的区域我们不需要进行绘制,否则会消耗相当大的资源。
6、不要给cell动态添加subView
在初始化cell的时候就将所有需要展示的添加完毕,然后根据需要来设置hide属性显示和隐藏。
7、异步化UI,不要阻塞主线程
我们时常会看到这样一个现象,就是加载时整个页面卡住不动,怎么点都没用,仿佛死机了一般。原因是主线程被阻塞了。所以对于网路数据的请求或者图片的加载,我们可以开启多线程,将耗时操作放到子线程中进行,异步化操作。这个或许每个iOS开发者都知道的知识,不必多讲。
8、滑动时按需加载对应的内容
如果目标行与当前行相差超过指定行数,只在目标滚动范围的前后指定3行加载。
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset{
NSIndexPath *ip = [self indexPathForRowAtPoint:CGPointMake(0, targetContentOffset->y)];
NSIndexPath *cip = [[self indexPathsForVisibleRows] firstObject];
NSInteger skipCount = 8;
if (labs(cip.row-ip.row)>skipCount) {
NSArray *temp = [self indexPathsForRowsInRect:CGRectMake(0, targetContentOffset->y, self.width, self.height)];
NSMutableArray *arr = [NSMutableArray arrayWithArray:temp];
if (velocity.y<0) {
NSIndexPath *indexPath = [temp lastObject];
if (indexPath.row+33) {
[arr addObject:[NSIndexPath indexPathForRow:indexPath.row-3 inSection:0]];
[arr addObject:[NSIndexPath indexPathForRow:indexPath.row-2 inSection:0]];
[arr addObject:[NSIndexPath indexPathForRow:indexPath.row-1 inSection:0]];
}
}
[needLoadArr addObjectsFromArray:arr];
}
}
记得在tableView:cellForRowAtIndexPath:方法中加入判断:
if (needLoadArr.count>0&&[needLoadArr indexOfObject:indexPath]==NSNotFound) {
[cell clear];
return;
}
滑动很快时,只加载目标范围内的cell,这样按需加载(配合SDWebImage),极大提高流畅度。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。
# ios
# uitableview优化
# uitableview卡顿
# 性能优化
# iOS中常见的视图和图片处理示例详解
# 详解IOS图片压缩处理
# iOS图片实现可拉伸不变形的处理操作
# iOS程序性能优化的技巧
# iOS开发教程之常见的性能优化技巧
# iOS性能优化教程之页面加载速率详解
# iOS性能优化浅析
# 详解优化iOS程序性能的25个方法
# IOS 性能优化中离屏渲染
# iOS开发中UITableview控件的基本使用及性能优化方法
# iOS 下的图片处理与性能优化详解
# 加载
# 复用
# 都是
# 绑定
# 不需要
# 按需
# 就会
# 如果你
# 还没有
# 放在
# 也会
# 在这个
# 将会
# 最多
# 就不
# 说了
# 两种
# 可以用
# 设为
# 将其
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Laravel如何为API生成Swagger或OpenAPI文档
浅述节点的创建及常见功能的实现
网页制作模板网站推荐,网页设计海报之类的素材哪里好?
Laravel任务队列怎么用_Laravel Queues异步处理任务提升应用性能
javascript中对象的定义、使用以及对象和原型链操作小结
lovemo网页版地址 lovemo官网手机登录
如何快速配置高效服务器建站软件?
图册素材网站设计制作软件,图册的导出方式有几种?
高防服务器:AI智能防御DDoS攻击与数据安全保障
用v-html解决Vue.js渲染中html标签不被解析的问题
Bootstrap整体框架之JavaScript插件架构
EditPlus中的正则表达式 实战(1)
如何快速搭建二级域名独立网站?
如何在IIS中配置站点IP、端口及主机头?
Midjourney怎么调整光影效果_Midjourney光影调整方法【指南】
b2c电商网站制作流程,b2c水平综合的电商平台?
详解Oracle修改字段类型方法总结
UC浏览器如何切换小说阅读源_UC浏览器阅读源切换【方法】
Laravel怎么清理缓存_Laravel optimize clear命令详解
如何做网站制作流程,*游戏网站怎么搭建?
详解jQuery中基本的动画方法
微博html5版本怎么弄发超话_超话进入入口及发帖格式要求【教程】
Android中AutoCompleteTextView自动提示
实例解析angularjs的filter过滤器
Laravel如何编写单元测试和功能测试?(PHPUnit示例)
laravel怎么用DB facade执行原生SQL查询_laravel DB facade原生SQL执行方法
uc浏览器二维码扫描入口_uc浏览器扫码功能使用地址
怎么制作网站设计模板图片,有电商商品详情页面的免费模板素材网站推荐吗?
如何快速生成高效建站系统源代码?
浅谈javascript alert和confirm的美化
html文件怎么打开证书错误_https协议的html打开提示不安全【指南】
Android仿QQ列表左滑删除操作
如何在Windows虚拟主机上快速搭建网站?
Laravel Fortify是什么,和Jetstream有什么关系
购物网站制作费用多少,开办网上购物网站,需要办理哪些手续?
详解Android图表 MPAndroidChart折线图
PHP的CURL方法curl_setopt()函数案例介绍(抓取网页,POST数据)
香港服务器租用每月最低只需15元?
Laravel如何保护应用免受CSRF攻击?(原理和示例)
Android实现代码画虚线边框背景效果
如何用狗爹虚拟主机快速搭建网站?
Linux网络带宽限制_tc配置实践解析【教程】
郑州企业网站制作公司,郑州招聘网站有哪些?
如何快速搭建高效香港服务器网站?
什么是javascript作用域_全局和局部作用域有什么区别?
如何在云虚拟主机上快速搭建个人网站?
网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?
Laravel怎么实现支付功能_Laravel集成支付宝微信支付
Laravel如何配置Horizon来管理队列?(安装和使用)
网站视频制作书签怎么做,ie浏览器怎么将网站固定在书签工具栏?

