天天看點

CALayer - 10

前面總結了那麼多CALayer的屬性和知識點,我們來理一理這貨究竟和UIView的差別和聯系是什麼,這也是面試常常有的難題!!

一番搜尋,找到一個很多的解析:http://www.jianshu.com/p/079e5cf0f014 , 大牛就是大牛!

先看看大神怎麼總結的:

CALayer - 10

根據文頂頂大神的教程,我們可以知道UIView作為CALayer的管理者,之是以能夠顯示内容,是因為CALayer層在螢幕的的繪制。而UIView繼承UIResponder類,具備事件響應的能力,CALayer不具備,但是由于輕量的原因性能上更高

這裡我們對比一下UIView CALayer 常見的相似的屬性和方法:

1.

CALayer - 10

2.

CALayer - 10

3.

CALayer - 10

4.

CALayer - 10

5.

CALayer - 10

6.

CALayer - 10

當然還有其他非常相似的屬性和方法,我們先不做細糾了

按照大牛的方法來我們繼承兩個UIView 和 CALayer 類,并重寫UIView裡面 layClass方法,跟蹤到底兩者關系和發生了什麼事情!

.h檔案:

#import <UIKit/UIKit.h>

@interface CustomerView : UIView

@end


#pragma mark - CustomerLayer.

@interface CustomerLayer : CALayer

@end           

.m檔案:

#import "CustomerView.h"

@implementation CustomerView


- (id)init
{
    self = [super init];
    
    if (self)
    {
        NSLog(@"CustomerCustomer init");
    }
    
    return self;
}


+ (Class)layerClass
{
    return [CustomerLayer class];
}

- (void)setFrame:(CGRect)frame
{
    [super setFrame:frame];
}

- (void)setCenter:(CGPoint)center
{
    [super setCenter:center];
}

- (void)setBounds:(CGRect)bounds
{
    [super setBounds:bounds];
}

- (void)setBackgroundColor:(UIColor *)backgroundColor
{
    [super setBackgroundColor:backgroundColor];
}


@end



#pragma mark - CustomerLayer.

@implementation CustomerLayer

- (instancetype) init
{
    self = [super init];
    
    if (self)
    {
        NSLog(@"CustomerLayer init");
    }
    
    return self;
}

+ (instancetype) layer
{
    return [CustomerLayer layer];
}

- (void)setFrame:(CGRect)frame
{
    [super setFrame:frame];
}


- (void)setPosition:(CGPoint)position
{
    [super setPosition:position];
}

- (void)setBounds:(CGRect)bounds
{
    [super setBounds:bounds];
}

- (void)setBackgroundColor:(CGColorRef)backgroundColor
{
    [super setBackgroundColor:backgroundColor];
}

@end           

在上面每一個方法都打一個斷點,可以發現,調用順序大緻如下:

init(UIView) -> layerClass(UIView) -> init(CALayer) -> setBounds(CALayer) -> setFrame(CALayer)*2 -> setPosition(CALayer) -> setBounds(CALayer) -> 開始彈出界面

當調用到layer建立了類之後我們可以看到:

CALayer - 10

可以看到UIView調用了一個私有方法,為什麼是私有方法呢?因為在頭檔案是看不到這個方法的!根據語義上可以知道:根據Frame來建立Layer,而且這個方法的調用順序在layerClass之後。

是以大神就猜測到UIView的setCenter 和 setBounds是不是直接根據它自身的CALayer的setPosition 和 setBounds來實作的呢?這個回想起,如果你直接setBounds和setCenter會錯位,是不是一個道理?這也是iOS的不足,我們往往難以知道源碼(閉源),進而難以像安卓一樣知道源碼實作,這個可以參考一下iOS的逆向工程

摘抄一段:

View中frame getter方法,bounds和center,UIView并沒有做什麼工作;它隻是簡單的各自調用它底層的CALayer的frame,bounds和position方法。

道理

參考:

http://www.jianshu.com/p/079e5cf0f014

http://www.cocoachina.com/industry/20131209/7498.html