UILabel的DrawDrect方法

一、问题

  如果继承UILabel实现自己的一个Label,并且在子类的DrawRect方法中留空,什么都不写,会发生什么?

  代码如下:

  VC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@interface ViewController ()
 
@property (nonatomic, strong) DrawTestLabel *dwLabel;
 
@end
 
@implementation ViewController
 
- (DrawTestLabel *)dwLabel
{
    if(!_dwLabel) {
        _dwLabel = [[DrawTestLabel alloc] init];
        _dwLabel.textAlignment = NSTextAlignmentCenter;
    }
     
    return _dwLabel;
}
 
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    [[self view] setBackgroundColor:[UIColor greenColor]];
    [[self dwLabel] setFrame:CGRectMake(0, 0, 200, 50)];
    [[self view] addSubview:[self dwLabel]];
    [[self dwLabel] setText:@"Hello"];
    [[self dwLabel] setCenter:[self view].center];
}
 
 
@end

  Label

1
2
3
4
5
6
7
8
9
10
@implementation DrawTestLabel
 
 
- (void)drawRect:(CGRect)rect {
    // Drawing code
//    [super drawRect:rect];
}
 
 
@end

  注释调调用父类的DrawRect方法之后,会发现屏幕上面什么都没有

  打开Xcode调试之后,会发现存在一个透明的图层

  

 

二、问题分析

  我们知道,UIView和Layer的关系,Layer负责画面渲染,UIVIew负责事件响应;

  在CALayer中通过实现 CALayerDelegate来实现画面的绘制,通常一个layer的delegate是UIView自身。

  CALayerDelegate 的方法 drawlayer:incontext方法在每次绘制的时候,会调用UIView的Drawrect方法,在UIView实现了DrawRect的方法下。

  

  

  那么上面自己继承的UILbel,重写Drawrect方法之后,大致的逻辑如下

  1、CALayer接受到系统的回调,开始渲染

  2、系统发现layer(Label)实现了Drawrect方法,那么会创建一个透明的画布,大小是UILabel的发小,scale是屏幕的scale

  3、通过delegate调用Drawrect方法,在这个画布之上绘制内容

  4、新的UILabel通过TextKit(底层是CoreText)来绘制文字到这个画布之上,这一段是在CPU上完成的

  5、绘制完成的bitmap ,再一次Runloop循环中,会通过系统统一提交给后台的renderserver

  6、render server进程处理不同的图层,通过操作GPU进行叠加渲染操作

  

  为什么Drawrect消耗比较高?

  因为绘制在CPU上面操作

  绘制完成的bitmap,会通过跨进城IPC传递给render server存在系统调用消耗

  render 传递内存中的bitmap到GPU的缓存上面生成纹理 ,再次产生消耗

 

  普通的UIView通过设置属性的方式,不涉及到传递大块内存的操作,这些类似背景色、透明度、都是通过renderserver来完成的,GPU操作效率会比较高。

  

  

posted @   兜兜有糖的博客  阅读(709)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
历史上的今天:
2018-06-15 AutoLayout + UILabel布局
2018-06-15 ReplayKit2 有线投屏项目-反向Socket实现
点击右上角即可分享
微信分享提示