一、问题

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

  代码如下:

  VC

@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

@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操作效率会比较高。

  

  

UILabel的DrawDrect方法的更多相关文章

  1. 重写UIlabel的setText:方法,过滤或者拦截text设置

    因为项目中很多地方都有对UIlabel的赋值,但是text.length == 0 或者为空时并没有去给默认值,导致很多界面空间是白板, 所以不想一个一个去改.希望能重写UIlabel 的setTex ...

  2. 获取UILabel宽度的方法

    - (CGFloat)labelLength:(NSString *)str font:(CGFloat)font{ str = ISSTRING(str) ? str : @"" ...

  3. UILabel的使用方法

    UILabel 就是一个显示文字的控件,可以设置文字的各种属性. 构造方法:     //通过设置Label的边框来初始化UILabel     labelOfSlider = [[UILabelal ...

  4. IOS 学习笔记(4) 控件 标签(UILabel)的使用方法

    虽说Label的中文翻译是标签标记,但它其实是一个静态文本内容的展现控件. 一般来说,UILabel只是一个只读的文本视图,开发者可以利用UiLabel来展示内容长度有固定上限的文字内容.并且,UIL ...

  5. UILabel设定行间距方法

    NSString *textStr = @"iPhone规定:任何应用想访问麦克风,必须被授权麦克风服务.请进入"设置"->"隐私"->& ...

  6. UILabel顶部对齐解决方法(转载)

    问题 我有一个UILabel高度最多能显示两行,如果里面内容只有一行,它是垂直居中的.怎么能让它顶端对齐呢?   回答 答案1:用sizeToFit改变UILabel的高度 nevan king,19 ...

  7. UILabel的顶对齐解决方法

    对于有多行文字的UILabel而言,需要设置UILabel的numberoflines属性,此属性默认是1,也就是只显示一行,多余的会以尾部,中间的方式进行截断,具体要看你的初始设置. 在这里可以将其 ...

  8. IOS UIlabel设置文本距离边框距离

    自定义UILabel 继承 UILabel 重写drawTextInRect 方法具体如下: CGRect rect = CGRectMake(rect.origin.x + 5, rect.orig ...

  9. iOS开发基础控件--UILabel

    UILabel 的常见属性和方法: //创建UIlabel对象 UILabel* label = [[UILabel alloc] initWithFrame:self.view.bounds]; / ...

  10. iOS运用runtime全局修改UILabel的默认字体

    iOS运用runtime全局修改UILabel的默认字体 一.需求背景介绍 在项目比较成熟的基础上,遇到了这样一个需求,应用中需要引入新的字体,需要更换所有Label的默认字体,但是同时,对于一些特殊 ...

随机推荐

  1. 重学c#系列——linq(4) [三十]

    前言 简单介绍一下linq 查询表达式. 正文 上文其实已经介绍了查询表达式了. 但是呢,这里就介绍一些复杂一点的. 这里不会去介绍查询表达式,而是直接介绍一些复杂的. let 字句. static ...

  2. 使用EPLAN做项目的收获点

    收获点如下: 1.消息检查功能. 最具有代表性的EPLAN软件的辅助检查功能.通过自带检查可以发现设计的错误和警告. 2.导线表导出功能. 使用导入模版.宏设置,导出对应线号表. 此类接线通过一个导线 ...

  3. JavaScript中的变量提升本质

    JavaScript中奇怪的一点是你可以在变量和函数声明之前使用它们.就好像是变量声明和函数声明被提升了代码的顶部一样. sayHi() // Hi there! function sayHi() { ...

  4. iframe跨域,获取iframe中元素

    1.需求让iframe嵌入页面,并且没有滚动条,也就是相当于两个页面拼接在一起 跨域解决,通过框架配置代理 proxy: { '/medical': { target: 'https://exampl ...

  5. 01_Vue技术-Hello案例分析

    初始vue:       1.想让vue工作,就必须创建一个Vue实例,且要传入一个配置对象:       2.root容器里的代码依然符合html规范,只不过混入了一些特殊的vue语法:       ...

  6. Apache Flink在 bilibili 的多元化探索与实践

    简介: bilibili 万亿级传输分发架构的落地,以及 AI 领域如何基于 Flink 打造一套完善的预处理实时 Pipeline. 本文由 bilibili 大数据实时平台负责人郑志升分享,本次分 ...

  7. WPF开源轻便、快速的桌面启动器

    前言 今天大姚给大家分享一款WPF开源.简单.轻便.快速的桌面启动器(支持多主题.多语言:简体中文.繁体中文.英文等):CurvaLauncher. WPF介绍 WPF 是一个强大的桌面应用程序框架, ...

  8. 5.k8s Service四层负载:服务端口暴露

    题目一:暴露服务service 设置配置环境: [candidate@node-1] $ kubectl config use-context k8s Task 请重新配置现有的 deployment ...

  9. foreach更改element内容后this到data不生效导致页面数据无变化

    list.forEach(element => {  element = element.split('^')    console.log(element)  }) 数据已经被更改,但在外部t ...

  10. 记录一次fs通话无声的问题

    概述 freeswitch是一款简单好用的VOIP开源软交换平台. fs的实际应用中,由于网络.配置等问题,经常会产生通话无声的问题. 环境 CentOS 7.9 freeswitch 1.10.7 ...