iOS开发中的性能优化和调试

1,292 阅读7分钟

在开始这篇文章之前,先说几个概念性的东西。 CPU 和GPU

关于绘图和动画有两种处理方式CPU(中央处理器)和GPU(图形处理器),CPU的工作都在软件层面,而GPU的在硬件层面。

总的来说,可以使用CPU做任何事情,但是对于图像的处理,通常GPU会更快,所以,我们想尽可能的把屏幕渲染的工作交给硬件去处理,而问题在于GPU并没有无限制处理的性能,一旦资源用尽,即使CPU并没有完全占用,GPU性能还是会下降。所以,目前大多的性能优化都是关于智能利用GPU和CPU,平衡它们之间工作负载。

测量,而不是猜测

如何测量,第一步就是确保在真实环境下测试你的程序

真机测试,而不是模拟器

模拟器运行在Mac上,然而Mac上的cpu比ios设备要快很多,相反,Mac上的GPU和ios设备上的不一样,模拟器不得已需要在软件层面(CPU)模拟ios设备,所以GPU的相关操作在模拟器上面运行的会更慢

另一件重要的就是性能测试的时候一定要用发布配置,而不是调试模式,因为当用发布环境打包的时候,编译器会引入一些提高性能的优化,比如:去除调试符号或者移除并重新组织代码,因为可以自己做到这些,比如禁用NSlog、print语句,因为 ,只需要关心发布性能。

测试帧率

Core Animation可以用来检测应用内的FPS,当FPS 低于45的时候,用户就会察觉到到滑动有卡顿。理论上60最佳,实际过程中59就可以了。

点击模拟器,然后在点击Debug,会发现如下几个名词。或者选择instruments工具中的Core Animation工具(如下图右下角),也会出现以下几个名词。接下来分别解释一下这几个名词:color blended Layers、color misaligned Layers、color copied images、color offScreen-Rendered Yellow。

1、color blended Layers(混合图层):对屏幕的混合区域从绿到红的叠加。由于重绘的原因,混合(视图重叠)对GPU性能有影响。如:空视图view的背景为绿色,添加半透明图片(avatar_vip界面上的VIP小图)后,图片的区域变成红色,这种情况对系统性能影响较大。

png图片是支持透明的,对系统性能也会有影响的

开发设置颜色最好不要设置透明颜色,因为透明颜色的图层和其他图层重叠在一块的部分,系统会做处理,这种处理是比较消耗资源的。 2、color misaligned Layers:图片的拉伸。如果显示黄色,最好考虑怎样将他变为绿色或者不显示。 所谓的拉伸就是设置的大小和图片本省的大小不一致,一般只要设置图片,就会存在拉升。实际上设置填充模式就是为了解决拉伸效果对性能的影响。

3、color copied images(很少用到) 复制的图片,开发中很少碰到,一般动画中core Animation 偶尔会自动生成图片,对系统性能影响很大。

4、color offScreen-Rendered Yellow

称为离屏渲染:是指在屏幕外部不可见部分或异步操作,准备好图片。优点:提前画好图片。 缺点:会在CPU和GPU之间频繁切换,一会计算坐标,一会画图。会导致CPU消耗高些,但现实性能稍微好些。一般会用shadowPath和shouldRasterise(栅格化)来优化。

在说明性能优化之前要说一点非常重要的:

所谓的性能优化一般都是在运行和内存之间切换,平衡两者的负荷。具体的性能到底好不好,一定要通过实际测试才来决定到底用不用采取下面的几种优化方案之一。试想,如果表格刷新帧率已经非常接近60了,但是还想进一步采取缓存行高来优化项目。很肯定的说,这种做法是不明智的,因为刷新帧率已经非常接近60了,即使再怎么优化也不可能突破60这个数值,反而采取缓存行高的方式会消耗内存,对整个项目的优化百害而无一利。

表格性能优化的七种方案:

1、如果要提高表格的性能,最重要的是减少计算,能够保证每一帧都完成计算,从而达到流畅的效果。(主要解决方案是:行高一定要缓存,请求到数据后提前计算行高即可。)

2、不要动态创建子视图,而不是动态的去创建子视图。即所有的子视图都预先给创建好,不需要显示的时候直接通过设置hidden属性,而不是动态的通过addsubview去控制。

3、所有的子视图都要制定背景颜色(如UIViewController中不设置背景颜色,会出现卡顿现象)。

4、所有的颜色都不要使用alpha,一旦涉及alpha就会涉及多个图层渲染的计算,运算量会很大,对资源的消耗会非常巨大。

5、栅格化(这是美工的术语):将cell中的所有内容,生成一张独立的图像。在屏幕滚动时,只显示图像。但是有一点要注意,使用栅格化的时候一定要设置屏幕分辨率。针对只一点优化,只要在自定义cell类中的初始化发放中写下如下两行代码:

self.layer.shadowPath = YES;
self.layer.rasterizationScale = [UIScreen mainScreen].scale;

设置完这两句话后,点击Core Animation中右下角的Color Hits Green And Misses Red会发现在滚动屏幕的时候,会出现部分绿色,这是因为离屏渲染会缓存部分生成的图像。

6、异步绘制。如果cell布局比较复杂建议使用异步绘制,其他情况下不建议使用。同样也是在自定义cell类中的初始化中完成,只要写上一句代码即可。

self.layer.drawsAsynchronously = YES;

7、针对混合图层和图片拉升效果引起的性能问题,一般可以通过绘制指定尺寸大小、不透明的图片来优化性能。如下是两个代码片段分别针对这一点绘制指定尺寸和圆角图片。

- (UIImage *)imageWithSize:(CGSize )size backColor:(UIColor *)backColor{
    CGRect rect = CGRectMake(0, 0, size.width, size.height);
    //1.上下文  ->在内存中开辟一个地址,这和屏幕显示无关
    //参数 1.绘图尺寸  2.是否不透明:false(透明)/true(不透明)  3.屏幕的分辨率,默认如果不指定,默认的图像显示1.0的分辨率,图像质量不好,可以指定为0,会选择当前屏幕的分辨率
    //第二个参数,一般设置为true更好些,会避免图层重叠导致的混合渲染
    UIGraphicsBeginImageContextWithOptions(size, YES, 0);
     //2.绘图 drawInRect就是在指定区域内拉伸屏幕  核心绘图的重点:路径
    //设置背景颜色
    [backColor setFill];
    UIRectFill(rect);
    [self drawInRect:rect];
     //3.取得结果
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    //4.关闭上下文
    UIGraphicsEndImageContext();
    
    return image;
}

绘制指定尺寸大小的图片

- (UIImage *)circleImageWithSize:(CGSize )size backColor:(UIColor *)backColor lineColor:(UIColor *)lineColor lineWidth:(CGFloat)linewidth{
      CGRect rect = CGRectMake(0, 0, size.width, size.height);
    //1.上下文  ->在内存中开辟一个地址,这和屏幕显示无关
    //参数 1.绘图尺寸  2.是否不透明:false(透明)/true(不透明)  3.屏幕的分辨率,默认如果不指定,默认的图像显示1.0的分辨率,图像质量不好,可以指定为0,会选择当前屏幕的分辨率
    //第二个参数,一般设置为true更好些,会避免图层重叠导致的混合渲染
    UIGraphicsBeginImageContextWithOptions(size, YES, 0);
    //2.绘图 drawInRect就是在指定区域内拉伸屏幕  核心绘图的重点:路径
     //a.背景填充颜色
    [backColor setFill];
    UIRectFill(rect);
    //b.实例化一个圆形的路径
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:rect];
     //c.进行路径裁剪 --后续的绘图,都会在圆形路径内部,外部的全部干掉
    [path addClip];
    //d.绘图
    [self drawInRect:rect];
     //f.绘制边线
    [lineColor setStroke];
    path.lineWidth = linewidth;
    [path stroke];
    
    //3.取得结果
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    //4.关闭上下文
    UIGraphicsEndImageContext();
    
    return image;

}

作者:ZhengYaWei

链接:www.jianshu.com/p/6ae6acce5…

来源:简书

加小编QQ :2507671038

微信:15388944845