一、问题

  如果继承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# 优化代码的一些规则——用委托表示回调[五]

    前言 委托为什么可以作为回调? 因为委托可以作为方法的参数. 正文 通过委托,是一种定义类型安全回调. 记得第一个接触委托的时候,是老师讲的,后来真正用的是完成学期项目,一个winform,委托作为事 ...

  2. 【Azure APIM】列举几种在APIM 策略中的主动生产的错误语句

    问题描述 在为APIM服务配置了诊断日志(Diagnostic Setting),把日志收集在Log A Workspace中,需要验证日志中是否能查看到请求的错误信息. 所以想人为的来制造一些错误. ...

  3. 物联网浏览器(IoTBrowser)-整合机器学习yolo框架实现车牌识别

    最近一段时间在研究AI技术在.Net平台的使用,目前AI绝大部分是使用Python开发,偶然一次在头条看到一篇ML.NET的介绍,是Net平台下开放源代码的跨平台机器学习框架.ML.NET详细介绍 h ...

  4. 剑指 Offer 58 - II(Java)-左旋转字符串(简单)

    题目: 字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部.请定义一个函数实现字符串左旋转操作的功能.比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位 ...

  5. 技术干货 | 阿里云数据库PostgreSQL 13大版本揭秘

    简介: 阿里云RDS PostgreSQL是一款兼容开源PostgreSQL的全托管云数据库产品,自2015年首次发布以来,根据用户需求不断升级迭代,已支持9.4.10.11.12等多个版本,覆盖了高 ...

  6. 5分钟搞定Loki告警多渠道接入

    ​简介: Loki是受Prometheus启发的水平可扩展.高可用.多租户日志聚合系统.用户既可以将Loki告警直接接入SLS开放告警,也可以先将Loki接入Grafana或Alert Manager ...

  7. [FE] uni-app 安装 uview-ui 的两种方式

    一. 下载的方式安装 就是把源码放到项目根目录中,然后引入 scss.js,并配置 easycom 模式. https://www.uviewui.com/components/install.htm ...

  8. dotnet 记 TaskCompletionSource 的 SetException 可能将异常记录到 UnobservedTaskException 的问题

    本文将记录 dotnet 的一个已知问题,且是设计如此的问题.假定有一个 TaskCompletionSource 对象,此对象的 Task 没有被任何地方引用等待.在 TaskCompletionS ...

  9. WPF 修复 ContextMenu 在开启 PerMonitorV2 后所用 DPI 错误

    本文告诉大家如何修复 WPF 的 ContextMenu 在开启 PerMonitorV2 之后,在双屏不同的 DPI 的设备上,在副屏弹出的 ContextMenu 使用了主屏的 DPI 导致缩放错 ...

  10. 2019-8-31-C#-转换类型和字符串

    title author date CreateTime categories C# 转换类型和字符串 lindexi 2019-08-31 16:55:58 +0800 2018-2-13 17:2 ...