美文网首页将来跳槽用
iOS开之优化大全

iOS开之优化大全

作者: 黄成瑞 | 来源:发表于2019-04-04 17:01 被阅读0次

    最近工作不是很忙,来对一些开发中实用的知识点进行一个总结,方便之后查阅,也希望可以帮助到大家~

    你要知道:优化性能会降低开发速度的~我们可以利用使用一些比较完善的组件(YYKit)

    大纲
    一、UITableView的优化
    二、网络请求的优化
    

    一、UITableView的优化

    UITableView是我们在开发中经常会用到的,那么深入的去学习如何优化TableView显得尤为重要了,首先我们要知道为什么TableView会出现卡顿现象?这里我们需要知道两个概念,CPU(负责视图相关的计算工作并告知GPU如何绘制)、GPU(图形的绘制和渲染等工作),屏幕刷新周期平均每秒60次,所为掉帧就是因为CPU或者GPU压力过大导致的,从而造成了卡顿现象。TableView在滑动时,会频繁出现对象创建、属性修改、布局计算、文本绘制、图形生成等消耗资源的操作,所以,我们的优化主要是如何在这一秒内减少它们的负荷从而保证他们能够顺利完成。

    1.避免主线程阻塞

    获取数据、数据处理等耗时操作应该放入后台线程异步处理,处理好后再通知主线程刷新界面。比如我们常用的网络请求第三方都是在后台线程完成的,但是回调回来之后是在主线程,这时我们需要手动管理线程,对负责的数据处理再次放入后台处理,然后再回到主线程刷新界面。

    // 1.异步处理数据(字典转模型、计算model的数据、布局等参数)
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^ {
      // 2.回到主线程刷新界面
      dispatch_async(dispatch_get_main_queue(), ^ {
      });
    });
    备注:UIKit和CoreAnimation相关操作必须在主线程中执行、其他可以在后台线程异步执行(异步绘制等)
    
    2.避免频繁的对象创建

    因为对象的创建会发送内存分配、属性调整等原因,所以,我们要尽量用清亮的对象代替重量的对象,比如CALayer代替UIView,多利用缓存思想,对象创建后混存起来,需要时候拿出来用,合理利用内存开销,减少CPU开销。UITableView的重用机制就是用来缓存的哦~还有就是当我们给Cell赋model时,重复计算,重复对象创建,还都是在主线程中执行,类似于这样的操作我们都可以放到模型转化时就计算好了,这样可以避免主线程阻塞还可以避免对象的频繁创建。(缓存Cell高度:高度计算好放在Model里或者存到一个数组中,优先考虑第一种)

    3.减少对象的属性赋值操作

    对UIView的Frame/bounds等属性赋值操作会消耗较大的CPU,普通的对象也会消耗CPU
    拓展:CALayer内部本身没有属性,当调用属性方法时,内部通过运行时resolveInstanceMethod为对象添加一个临时方法,并把对应属性值保存到内部的字典中,还会通知Delegate、创建动画等等,非常消耗资源。而我们UIView的Frame、Bounds、transform都是CALayer映射出来的,所以对UIView属性调整消耗资源远大于一般的属性,应该减少不必要的修改。追求性能就多些几个Cell保证Frame不会频繁改变,不追求就写在一个中。

    4.异步绘制

    文本渲染、图像绘制都是比较消耗性能的操作,比如UILabel等控件都是在主线程进行文本绘制,这会对性能产生较大的影响。异步绘制的思想就是尽量把需要显示的内容放在异步线程绘制,然后绘制完成通知主线程显示。

    // 必须主线程中进行
    ImageView.image = image;
    // Image的绘制过程可以在异步线程操作dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^ {
      CGContextRef...
      dispatch_async(dispatch_get_main_queue(), ^ {
          imageView.image = image;
      });
    });
    
    
    
    5.简化视图结构

    因为GPU在绘制图像前会把重叠的视图进行混合,视图结构越复杂,这个操作越耗时,如果存在透明视图,混合过程会更复杂,所以:

    1.尽量避免复杂的图层结构
    2.少使用透明的视图
    3.不透明的视图设置opaque=YES;
    4.尽可能把视图异步绘制成一张图
    
    6.减少离屏渲染

    离屏渲染:GPU绘制图时是在屏幕缓冲区绘制的叫做当前屏幕渲染(On-Screen Rendering),由于某种特定条件GPU在当前屏幕缓冲区以外开辟新的缓冲区进行渲染操作就是离屏渲染(Off-Screen Rendering)
    因为它要创建新的缓冲区而且离屏渲染的整个过程,需要多次切换上下文环境:先是从当前屏幕(On-Screen)切换到离屏(Off-Screen);等到离屏渲染结束以后,将离屏缓冲区的渲染结果显示到屏幕上有需要将上下文环境从离屏切换到当前屏幕。而上下文环境的切换是要付出很大代价的。
    拓展:
    如何查看哪些控件发生了离屏渲染?使用Instruments工具来观察(观察手机屏幕,黄色标示就是发生了离屏渲染)
    我们开发中经常使用到圆角,cornerRadius+masksToBounds就会造成离屏渲染,解决方式为异步绘制一张圆角图片来显示,或者用一个圆角而中空的图来盖住。切割图片的圆角。

    6.TableView的刷新事件
    多使用:
    [tableview beginUpdates];
    [tableview insertRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationNone];
    [tableview endUpdates];
    少使用:
    [tableview reloadData];
    
    这样可以不用刷新所有行从而减少CPU压力,并且如果Cell采用了异步绘制reloadData会重新绘制很多次,会造成闪屏感觉
    
    7.避免复杂的Autolayout使得CPU消耗过多
    8.Cell高度的缓存

    二、网络请求的优化

    1.DNS映射优化

    无论是Http还是Socket,第一步都是DNS解析,这一步的优化对请求的延迟来说至关重要

    2.请求压缩优化

    DNS过后是TCP握手建立连接并发送请求数据,我们应该尽可能尝试压缩我们网络请求的业务数据,减少一个请求的IP包数量,从而让用户少经历一个RTT,降低请求延迟的用户感知。

    3.请求合并优化

    对于非关键性也无数据和实时性不高的请求来说通过合并请求的方式来减少和服务器的交互次数,降低服务器的压力并且合并之后再压缩能节约客户端的流量

    4.请求的安全性优化

    配合HTTPS来做到基本的网络安全优化

    5.合并的并发数优化

    有些业务场景会出现多个请求及中产生的情况,此时需要我们设置一个合理的并发数,如果并发数太小会导致影响其他请求,如果并发数太大会增加整体延迟,所以一定要合理哦~

    6.可靠性保障优化
    三类:(考虑到客户端流量、带宽、手机电量、服务器的压力等有限资源)
    1.关键核心业务数据期望能百分百送达服务器(持久化到DB中,失败加入重试队列,成功则移除重试队列,还要定时多久重试一次等)
    2.重要内容请求保证较高的请求成功率(失败后自动设置3次重试)
    3.一般性内容对于成功率无要求(无需过多在意)
    
    7.多通道

    除了HTTP外,有条件可以开设TCP和UDP,UDP通道可以在丢包率高的网络环境下极大提高请求成功率

    8.网络环境监控

    针对信号差的环境(电梯里)针对性的做请求重试

    9.请求成功率监控

    监控APP网络请求成功率,对于失败率高的带上也无数据网络环境参数等在用户不活跃的时候打包给服务端查看,从而进行优化

    参考文章
    深度优化iOS网络模块
    iOS开发——实战UITableview深度优化

    相关文章

      网友评论

        本文标题:iOS开之优化大全

        本文链接:https://www.haomeiwen.com/subject/nkgfiqtx.html