Notes

渲染原理

iOS 保持界面流畅的技巧 这篇文章干货满满,以前看得很迷茫,现在再看,清晰了很多。将其中部分的原理介绍整理一下,方便以后快查和回顾

CRT 显示器原理

CPU, GPU, 显示器协同工作

iOS 设备显示策略

iOS 设备使用双缓存 + 垂直同步

双缓冲

使用两个 缓冲区 ,提高效率 带来的问题: 视频控制器 读取数据未完成,GPU 将 视频控制器 的指针切换到另一个 缓冲区 ,造成旧的帧数据与新的帧数据重合,使得画面违和

垂直同步

CPU 将会等待上面提到的 VSync 信号,接收到后才会进行新一帧的渲染和缓冲区更新

带来的问题:消费更多的计算资源,带来部分的延迟

界面卡顿原理

更进一步的 CPU 与 GPU 协同工作原理

CPU 阶段


GPU 阶段

由工作流程可以知道,由于 垂直同步 机制,如果在一个 VSync 时间内,CPU 或 GPU 没有完成内容的提交,该一帧(B)的数据就会被丢弃,而上一帧(A)的内容保持不变,这时候又有新的一帧(C)补充过来,于是,就有了卡顿,跳帧的效果

CPU 资源消耗在哪里

对象创建

消耗


建议

对象调整

CALayer 与 UIView 的关系

由于 UIView 相关的显示属性(frame, bounds, transform) 都是 CALayer 属性映射过来,所以所有的起因都起于 CALayer

CALayer 的属性

建议:

对象销毁

不得已的时候,可以在后台释放对象

释放当前对实例的引用,并把实例扔到后台线程随便调用一下方法

NSArray *tmp = self.array;
self.array = nil;
dispatch_async(queue, ^{
    [tmp class];
});

布局计算

建议

自动布局

对复杂视图来说会有严重的性能问题

建议:

文本计算

文本显示原理

文本过多时,应使用底层的文本库进行自定义文本控件的定义,如 CoreText, CoreText 使用起来麻烦,但是可以直接获取到文本的宽高信息,占用内存也比较小

图片解码

图片解码原理

建议:

图像绘制

图像的绘制通常是指用那些以 CG 开头的方法把图像绘制到画布中,然后从画布创建图片并显示这样一个过程。这个最常见的地方就是 [UIView drawRect:] 里面了。由于 CoreGraphic 方法通常都是线程安全的,所以图像的绘制可以很容易的放到后台线程进行

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

GPU 消耗在哪里

GPU 的工作稍微简单:

纹理渲染

建议:

视图混合

建议:

图形生成

建议:

References