iOS YYKit–YYLabel源码分析

热门标签

特别声明:文章多为网络转载,资源使用一般不提供任何帮助,特殊资源除外,如有侵权请联系!

一、YYLabel实现的总体思路

其实YYLabel主要就是为了实现异步绘图,提高性能,为此做了好多东西。

1、使用自定义的Layer,YYAsyncLayer

2、在YYAsyncLayer中实现异步绘图,因为系统默认的绘图都是在主线程执行了的,这里要实现异步绘图,那么就得摈弃掉系统的绘图方法,自己去实现。所以这里得花费很多功夫。所以说,提高性能是要付出很多的。

二、下面开始进入代码分析:

(1)使用自定义的Layer,YYAsyncLayer

在YYLabel中重写了下面的方法:

+ (Class)layerClass {

return [YYAsyncLayer class];

}

就是修改了View的主Layer层,把YYAsyncLayer的实例作为主Layer层

(2)View与Layer的关系

View其实就是Layer的代理,Layer是View的底层实现,View是Layer的管理类。绘图和坐标等操作都是在Layer中实现的,View只是访问Layer中的相关方法。

(3)系统View的绘图过程:

1、调用setNeedsDisplay

2、调用Layer中的display方法

3、在display中会调用Layer的drawInContext方法

4、在drawInContext中会调用代理方法drawLayer:(CALayer *)layer

inContext:(CGContextRef)ctx,这就进入到View了

5、最后View在代理实现中调用了drawRect方法,这方法就是我们经常用到了那个。

我写了demo验证了上面的过程,结果如下:

iOS YYKit--YYLabel源码分析

(4) YYLabe的绘图过程

在YYAsyncLayer中,我们找到display方法:

- (void)display {

super.contents = super.contents;

[self _displayAsync:_displaysAsynchronously];

}

重写了display方法,但没有调用super方法,就是说上面的流程已经被打断了,那么view的系统绘图方法都不会被调用。

iOS YYKit--YYLabel源码分析

通过代理方法newAsyncDisplayTask得到了YYAsyncLayerDisplayTask类实例,再通过调用类实例的block方法直接返回到View中进行操作。作者打断了之前的绘图流程,但这里是通过block进入到UIView中进行绘图操作,这样就可以完全控制绘图过程。

在_displayAsync方法中:

iOS YYKit--YYLabel源码分析

可见,这里是在线程中操作的,先创建了上下文context,然后再调用代理方法:task.display(context, size,isCancelled),所以UIView在代理实现中的绘图操作都是在线程中执行的,这里就实现了异步绘图。

(5) newAsyncDisplayTask的代理实现

iOS YYKit--YYLabel源码分析

上面是得到一些绘图需要的参数,其中最主要的是YYTextLayout对象,里面包含了很多绘图需要的信息。

然后是block display方法:

iOS YYKit--YYLabel源码分析

上面提到这个block实在非主线程执行的,这里执行了真正的绘图操作,绘图操作方法:

[drawLayoutdrawInContext:context size:size point:point view:nil layer:nil debug:debug cancel:isCancelled];中。

具体的绘图还是挺复杂了,看起来有点吃力,以后有机会再研究下。好了,整个YYLabel的实现流程已经分析完成,是不是觉得源码作者很牛逼。作者为了实现异步绘图,花了好多的功夫。

 

标签:

未经允许不得转载:作者:SheaYang, 转载或复制请以 超链接形式 并注明出处 技术Dog|博客
原文地址:《iOS YYKit–YYLabel源码分析》 发布于2019-09-30

分享到:
赞(0) 打赏

评论 抢沙发

5 + 5 =


iOS YYKit–YYLabel源码分析

长按图片转发给朋友

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏

Vieu4.0主题
专业打造轻量级个人企业风格博客主题!专注于前端开发,全站响应式布局自适应模板。

登录

忘记密码 ?