前面總結了那麼多CALayer的屬性和知識點,我們來理一理這貨究竟和UIView的差別和聯系是什麼,這也是面試常常有的難題!!
一番搜尋,找到一個很多的解析:http://www.jianshu.com/p/079e5cf0f014 , 大牛就是大牛!
先看看大神怎麼總結的:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIyVGduV2QvwVe0lmdhJ3ZvwFM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2LcZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39DNxcTNxgTN3EjMwEDM2EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
根據文頂頂大神的教程,我們可以知道UIView作為CALayer的管理者,之是以能夠顯示内容,是因為CALayer層在螢幕的的繪制。而UIView繼承UIResponder類,具備事件響應的能力,CALayer不具備,但是由于輕量的原因性能上更高
這裡我們對比一下UIView CALayer 常見的相似的屬性和方法:
1.
2.
3.
4.
5.
6.
當然還有其他非常相似的屬性和方法,我們先不做細糾了
按照大牛的方法來我們繼承兩個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建立了類之後我們可以看到:
可以看到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