性能-CPU

对性能方面做了些文章材料收集

一、CPU 消耗型任务

1、布局计算

布局计算是 iOS 中最为常见的消耗 CPU 资源的地方,如果视图层级关系比较复杂,计算出所有图层的布局信息就会消耗一部分时间。因此我们应该尽量提前计算好布局信息,然后在合适的时机调整对应的属性。还要避免不必要的更新,只在真正发生了布局改变时再更新。

2、对象创建

对象创建过程伴随着内存分配、属性设置、甚至还有读取文件等操作,比较消耗 CPU 资源。尽量用轻量的对象代替重量的对象,可以对性能有所优化。比如 CALayer 比 UIView 要轻量许多,如果视图元素不需要响应触摸事件,用 CALayer 会更加合适。

通过 Storyboard 创建视图对象还会涉及到文件反序列化操作,其资源消耗会比直接通过代码创建对象要大非常多,在性能敏感的界面里,Storyboard 并不是一个好的技术选择。

对于列表类型的页面,还可以参考 UITableView 的复用机制。每次要初始化 View 对象时先根据 identifier 从缓存池里取,能取到就复用这个 View 对象,取不到再真正执行初始化过程。滑动屏幕时,会将滑出屏幕外的 View 对象根据 identifier 放入缓存池,新进入屏幕可见范围内的 View 又根据前面的规则来决定是否要真正初始化。

3、Autolayout

Autolayout 是苹果在 iOS6 之后新引入的布局技术,在大多数情况下这一技术都能大大提升开发速度,特别是在需要处理多语言时。比如阿拉伯语下布局是从右往左,通过 Autolayout 设置 leading 和 trailing 即可。

但是 Autolayout 对于复杂视图来说常常会产生严重的性能问题,对于性能敏感的页面建议还是使用手动布局的方式,并控制好刷新频率,做到真正需要调整布局时再重新布局。

4、文本计算

如果一个界面中包含大量文本(比如微博、微信朋友圈等),文本的宽高计算会占用很大一部分资源,并且不可避免。

一个比较常见的场景是在 UITableView 中,heightForRowAtIndexPath这个方法会被频繁调用,即使不是耗时的计算在调用次数多了之后也会带来性能损耗。这里的优化就是尽量避免每次都重新进行文本的行高计算,可以在获取到 Model 数据后就根据文本内容计算好布局信息,然后将这份布局信息作为一个属性保存到对应的 Model 中,这样在 UITableView 的回调中就可以直接使用 Model 中的属性,减少了文本的计算。

5、文本渲染
640.jpeg

屏幕上能看到的所有文本内容控件,包括 UIWebView,在底层都是通过 CoreText 排版、绘制为 Bitmap 显示的。常见的文本控件 (UILabel、UITextView 等),其排版和绘制都是在主线程进行的,当显示大量文本时,CPU 的压力会非常大。

这一部分的性能优化就需要我们放弃使用系统提供的上层控件转而直接使用 CoreText 进行排版控制。

Wherever possible, try to avoid making changes to the frame of a view that contains text, because it will cause the text to be redrawn. For example, if you need to display a static block of text in the corner of a layer that frequently changes size, put the text in a sublayer instead.

上面这段话引用自 iOS Core Animation: Advanced Techniques,翻译过来的意思就是说包含文本的视图在改变布局时会触发文本的重新渲染,对于静态文本我们应该尽量减少它所在视图的布局修改。

6、图像的绘制

图像的绘制通常是指用那些以 CG 开头的方法把图像绘制到画布中,然后从画布创建图片并显示的过程。前面的模块图里介绍了 CoreGraphic 是作用在 CPU 之上的,因此调用 CG 开头的方法消耗的是 CPU 资源。我们可以将绘制过程放到后台线程,然后在主线程里将结果设置到 layer 的 contents 中。代码如下:

    - (void)display {
        dispatch_async(backgroundQueue, ^{
            CGContextRef ctx = CGBitmapContextCreate(...);
            // draw in context...
            CGImageRef img = CGBitmapContextCreateImage(ctx);
            CFRelease(ctx);
            dispatch_async(mainQueue, ^{
                layer.contents = img;
            });
        });
    }
7、图片的解码

Once an image file has been loaded, it must then be decompressed. This decompression can be a computationally complex task and take considerable time. The decompressed image will also use substantially more memory than the original.
图片被加载后需要解码,图片的解码是一个复杂耗时的过程,并且需要占用比原始图片还多的内存资源。

为了节省内存,iOS 系统会延迟解码过程, 在图片被设置到 layer 的 contents 属性或者设置成 UIImageView 的 image 属性后才会执行解码过程,但是这两个操作都是在主线程进行,还是会带来性能问题。

如果想要提前解码,可以使用 ImageIO 或者提前将图片绘制到 CGContext 中,这部分实践可以参考 iOS Core Animation: Advanced Techniques

常用的 UIImage 加载方法有 imageNamed 和 imageWithContentsOfFile。其中 imageNamed 加载图片后会马上解码,并且系统会将解码后的图片缓存起来,但是这个缓存策略是不公开的,我们无法知道图片什么时候会被释放。因此在一些性能敏感的页面,我们还可以用 static 变量 hold 住 imageNamed 加载到的图片避免被释放掉,以空间换时间的方式来提高性能。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,016评论 4 62
  • 1 见过众多的人生轨迹,有安稳顺利的,有充满各种波折的,大多数是平淡乏味过完一生。见过各色人等,高尚的,卑劣的,从...
    任风南阅读 386评论 0 1
  • 一大早可能是因为最近的运气都太好,所以这个标题不由得被我记录。 我一直在朋友或是同事甚至是男朋友的眼里是一个极其恋...
    暮紫夕阅读 572评论 0 0
  • 不要为了奋勇杀敌。 而忘了回头看看。 那为你披上铠甲的人。
    9f8fffeae517阅读 288评论 2 1
  • 旧辞除岁引新回,尽余晖,万家帏,爆竹声声,通夜挑灯熙。祭祖祈安迎腊日,嘉平庆,厚丰牺。 忽闻炉灶郁香迷,紫光霓,百...
    诗酒慰年华的夏川阅读 179评论 0 2