1.首先UIView可以响应事件,UIView能接受用户交互,能够处理hit-test方法,UIView能够进行布局,Layer不可以
2.调用UIView的setFrame,它里面的CALayer会调用setFrame、 settPosition、setBounds方法,UIView并没有做什么工作;它只是简单的各自调用它内部CALayer的CALayer的frame,bounds和position方法.
如果对UIView设置bounds,直接会对UIView的layer设置bounds,如果调用UIView的layoutIfNeeded,将直接调用CALayer.
UIView本身更像是一个CALayer的管理器,访问它的跟绘图和跟坐标有关的属性,例如frame,bounds等,实际上内部都是在访问它所包含的CALayer的相关属性。
3.UIView是CALayer的Delegate

//CALayer的一个属性
@property(nullable, weak) id <CALayerDelegate> delegate;
//returns view's layer. Will always return a non-nil value. view is layer's delegate
可以看到 UIView 是 CALayer 的CALayerDelegate,我猜测是在代理方法内部[UIView(CALayerDelegate) drawLayer:inContext]调用 UIView 的 DrawRect方法,从而绘制出了 UIView 的内容.
4.UIView是在主线程使用CPU进行渲染的,耗费系统CPU,CALayer层级结构更简单,能够快速的渲染,,CALayer直接在GPU渲染,它发生在单独的线程上不会给CPU造成负担.
为什么不能直接对Frame的origin和size赋值?
customView.frame.origin.x = 10; //Expression is not assignable
如果你对Frame的origin和size直接赋值,你将会直接绕过UIView的setFrame:方法,不触发setter方法,UIView将没有机会监听到Frame的变化,UIView就不能去更新它的子视图以及去重绘它自己。
另外,为了KVO能够工作,要使用正确的setter方法或者点语法对Frame进行赋值。
网友评论