当前位置: 移动技术网 > IT编程>移动开发>IOS > 详细整理iOS中UITableView的性能优化

详细整理iOS中UITableView的性能优化

2019年07月24日  | 移动技术网IT编程  | 我要评论

绝命毒师第三季下载,最新个税法,全国钢材价格行情

一、介绍

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 uicollectionview实现横向滚动

    现在使用卡片效果的app很多,之前公司让实现一种卡片效果,就写了一篇关于实现卡片的文章。文章最后附有demo实现上我选择了使用uicollectionview ... [阅读全文]
  • iOS UICollectionView实现横向滑动

    本文实例为大家分享了ios uicollectionview实现横向滑动的具体代码,供大家参考,具体内容如下uicollectionview的横向滚动,目前我使... [阅读全文]
  • iOS13适配深色模式(Dark Mode)的实现

    iOS13适配深色模式(Dark Mode)的实现

    好像大概也许是一年前, mac os系统发布了深色模式外观, 看着挺刺激, 时至今日用着也还挺爽的终于, 随着iphone11等新手机的发售, ios 13系统... [阅读全文]
  • ios 使用xcode11 新建项目工程的步骤详解

    ios 使用xcode11 新建项目工程的步骤详解

    xcode11新建项目工程,新增了scenedelegate这个类,转而将原appdelegate负责的对ui生命周期的处理担子接了过来。故此可以理解为:ios... [阅读全文]
  • iOS实现转盘效果

    本文实例为大家分享了ios实现转盘效果的具体代码,供大家参考,具体内容如下demo下载地址: ios转盘效果功能:实现了常用的ios转盘效果,轮盘抽奖效果的实现... [阅读全文]
  • iOS开发实现转盘功能

    本文实例为大家分享了ios实现转盘功能的具体代码,供大家参考,具体内容如下今天给同学们讲解一下一个转盘选号的功能,直接上代码直接看viewcontroller#... [阅读全文]
  • iOS实现轮盘动态效果

    本文实例为大家分享了ios实现轮盘动态效果的具体代码,供大家参考,具体内容如下一个常用的绘图,主要用来打分之类的动画,效果如下。主要是ios的绘图和动画,本来想... [阅读全文]
  • iOS实现九宫格连线手势解锁

    本文实例为大家分享了ios实现九宫格连线手势解锁的具体代码,供大家参考,具体内容如下demo下载地址:效果图:核心代码://// clockview.m// 手... [阅读全文]
  • iOS实现卡片堆叠效果

    本文实例为大家分享了ios实现卡片堆叠效果的具体代码,供大家参考,具体内容如下如图,这就是最终效果。去年安卓5.0发布的时候,当我看到安卓全新的material... [阅读全文]
  • iOS利用余弦函数实现卡片浏览工具

    iOS利用余弦函数实现卡片浏览工具

    本文实例为大家分享了ios利用余弦函数实现卡片浏览工具的具体代码,供大家参考,具体内容如下一、实现效果通过拖拽屏幕实现卡片移动,左右两侧的卡片随着拖动变小,中间... [阅读全文]
验证码:
移动技术网