异步渲染(Asynchronous Rendering)
异步渲染主要指在后台线程(子线程)进行与界面显示相关的耗时操作,比如图片加载、文本排版、数据处理等,然后在主线程更新 UI。这种做法的主要目的是避免阻塞主线程,降低主线程的压力,以确保用户界面的流畅性和响应速度。
异步渲染通常使用 GCD 或 OperationQueue 进行后台线程的任务分发。
一 UIView绘制渲染原理和流程
- UIView调用setNeedsDisplay(setNeedsDisplay会调用自动调用drawRect方法);
- 系统会立刻调用view的layer的同名方法[view.layer setNeedsDisplay],之后相当于在layer上面打上了一个刷新标记;
- 然后再当前runloop将要结束的时候,才会调用CALayer的display函数方法,然后才进入到当前视图的真正绘制工作的流程当中;
- runloop即将结束, 开始视图的绘制流程;
系统默认绘制流程
- CALayer内部创建一个backing store(CGContextRef)();
- 判断layer是否有代理(1.有代理:调用delegete的drawLayer:inContext, 然后在合适的 实际回调代理, 在[UIView drawRect]中做一些绘制工作;2. 没有代理:调用layer的drawInContext方法。)
- layer上传backingStore到GPU, 结束系统的绘制流程;
异步绘制流程
- 某个时机调用setNeedsDisplay;
- runloop将要结束的时候调用[CALayer display]
- 如果代理实现了dispalyLayer将会调用此方法, 在子线程中去做异步绘制的工作;
- 子线程中做的工作:创建上下文, 控件的绘制, 生成图片;
- 转到主线程, 设置layer.contents, 将生成的视图展示在layer上面;
dispatch_async(dispatch_get_global_queue(0, 0), ^{
///获取当前上下文
UIGraphicsBeginImageContextWithOptions(size, false, scale);
//1.获取上下文
UIGraphicsGetCurrentContext();
//TODO
...............
//生成图片
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
///子线程完成工作, 切换到主线程展示
dispatch_async(dispatch_get_main_queue(), ^{
self.layer.contents = img;
})
});
第三方: YYKit
Graver