美文网首页ios开发那些事
iOS面试-UIView与CALayer

iOS面试-UIView与CALayer

作者: SK丿希望 | 来源:发表于2019-10-31 10:29 被阅读0次

    框架
    • CALayer 基于 QuartzCore 框架
    • UIView 基于 UIKit 框架
    父类
    • CALayer继承自NSObject
    • UIView继承自UIResponder
    小结

    因为UIView继承UIResponder,而UIResponder是拥有touches事件的,说明UIView能处理用户的触摸事件的,反之CALayer是不能处理事件的(但是可以通过对应的方法实现),由于CALayer不需要处理交互事件、所以是轻量级的、性能要比UIView高。

    CALayer添加点击事件
    • 通过 touchesBegan: withEvent 方法,监听屏幕点击事件,在这个方法中通过 convertPoint 找到点击位置,进行判断,如果点击了 layer 视图内坐标,就触发点击事件
    • 通过 hitTest方法找到包含坐标系的 layer 视图
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    //  方法一,通过 convertPoint 转为为 layer 坐标系进行判断
        CGPoint point = [[touches anyObject]   locationInView:self.view];
        CGPoint redPoint = [self.redLayer  convertPoint:point fromLayer:self.view.layer];
        if ([self.redLayer containsPoint:redPoint]) {
        NSLog(@"点击了calayer");
        }
    //  方法二 通过 hitTest 返回包含坐标系的 layer 视图
        CGPoint point1 = [[touches anyObject] locationInView:self.view];
        CALayer *layer = [self.view.layer hitTest:point1];
        if (layer == self.redLayer) {
           NSLog(@"点击了calayer");
        }
    }
    
    代码验证
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.aView = [[UIView alloc] init];
        self.aLayer = [[CALayer alloc] init];
        //比较UIView对象个CALayer对象在内存中的大小
        NSLog(@"self.aView对象实际需要的内存大小: %zd", class_getInstanceSize([self.aView class]));//480
        NSLog(@"self.aView对象实际分配的内存大小: %zd", malloc_size((__bridge const void *)(self.aView)));//480
        NSLog(@"self.aLayer对象实际需要的内存大小: %zd", class_getInstanceSize([self.aLayer class]));//24
        NSLog(@"self.aLayer对象实际分配的内存大小: %zd", malloc_size((__bridge const void *)(self.aLayer)));//32
    
        NSLog(@"------");
        //针对于UILabel 和 CATextLayer内存对比
        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(30, 300, 300, 44)];
        label.text = @"label";
        [self.view addSubview:label];
        
        CATextLayer *textLayer = [[CATextLayer alloc] init];
        textLayer.frame = CGRectMake(30, 400, 300, 44);
        textLayer.string = @"CATextLayer";
        [self.view.layer addSublayer:textLayer];
        
        //比较UILabel对象个CATextLayer对象在内存中的大小
        NSLog(@"label对象实际需要的内存大小: %zd", class_getInstanceSize([label class]));//744
        NSLog(@"label对象实际分配的内存大小: %zd", malloc_size((__bridge const void *)(label)));//752
        NSLog(@"textLayer对象实际需要的内存大小: %zd", class_getInstanceSize([textLayer class]));//32
        NSLog(@"textLayer对象实际分配的内存大小: %zd", malloc_size((__bridge const void *)(textLayer)));//32
        
        NSLog(@"------");
        //添加了一些设置, 比如字体大小, 颜色, 换行, 字体长度变化
        label.text = @"123456789012345678901234567890";
        label.font = [UIFont fontWithName:@"PingFangSC-Regular" size:12];
        label.textColor = [UIColor redColor];
        
        textLayer.string = @"123456789012345678901234567890";
        textLayer.font =  (__bridge CFTypeRef _Nullable)(@"PingFangSC-Regular");
        textLayer.fontSize = 12;
        textLayer.foregroundColor = [UIColor redColor].CGColor;
        //比较UILabel对象个CATextLayer对象在内存中的大小
        NSLog(@"label对象实际需要的内存大小: %zd", class_getInstanceSize([label class]));//744
        NSLog(@"label对象实际分配的内存大小: %zd", malloc_size((__bridge const void *)(label)));//752
        NSLog(@"textLayer对象实际需要的内存大小: %zd", class_getInstanceSize([textLayer class]));//32
        NSLog(@"textLayer对象实际分配的内存大小: %zd", malloc_size((__bridge const void *)(textLayer)));//32
    }
    
    打印结果
    2019-09-12 11:06:33.017943+0800 Demo[7030:27412457] self.aView对象实际需要的内存大小: 480
    2019-09-12 11:06:33.018123+0800 Demo[7030:27412457] self.aView对象实际分配的内存大小: 480
    2019-09-12 11:06:33.018249+0800 Demo[7030:27412457] self.aLayer对象实际需要的内存大小: 24
    2019-09-12 11:06:33.018367+0800 Demo[7030:27412457] self.aLayer对象实际分配的内存大小: 32
    2019-09-12 11:06:33.018478+0800 Demo[7030:27412457] ------
    2019-09-12 11:06:33.019261+0800 Demo[7030:27412457] label对象实际需要的内存大小: 744
    2019-09-12 11:06:33.019357+0800 Demo[7030:27412457] label对象实际分配的内存大小: 752
    2019-09-12 11:06:33.019443+0800 Demo[7030:27412457] textLayer对象实际需要的内存大小: 32
    2019-09-12 11:06:33.019542+0800 Demo[7030:27412457] textLayer对象实际分配的内存大小: 32
    2019-09-12 11:06:33.019651+0800 Demo[7030:27412457] ------
    2019-09-12 11:06:33.023849+0800 Demo[7030:27412457] label对象实际需要的内存大小: 744
    2019-09-12 11:06:33.024001+0800 Demo[7030:27412457] label对象实际分配的内存大小: 752
    2019-09-12 11:06:33.024106+0800 Demo[7030:27412457] textLayer对象实际需要的内存大小: 32
    2019-09-12 11:06:33.085927+0800 Demo[7030:27412457] textLayer对象实际分配的内存大小: 32
    
    • 由此看得出来, 在对象的内存分配中, CATextLayer的内存大小明显要比UIView要轻量的多.
    • 对于一些只是用来展示的控件,比如是UIlabel,或者是ImageView. 完全可以用Layer来代替.
    • 简单粗暴来理解:所有集成于UIView的控件,它们自身带有一个CALayer层, 所以UIView里面的东西会比CALayer中的要多.
    参考

    UIView和CALayer之间的关系
    UIView与CALayer的区别,很详细

    其它

    CALayer的属性和使用
    CALayer处理点击事件
    CALayer 添加事件处理的两种方法

    相关文章

      网友评论

        本文标题:iOS面试-UIView与CALayer

        本文链接:https://www.haomeiwen.com/subject/qkbovctx.html