ios开发那些事

iOS面试-UIView与CALayer

2019-10-31  本文已影响0人  SK丿希望

框架
父类
小结

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

CALayer添加点击事件
- (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 添加事件处理的两种方法

上一篇 下一篇

猜你喜欢

热点阅读