2019 iOS面試題大全---全方面剖析面試
- UIView與CALayer
- 事件傳遞與視圖響應鏈
- 圖像顯示原理
- UI卡頓掉幀原因
- 滑動優化方案
- UI繪制原理
- 離屏渲染
一、UIView與CALayer
<單一職責原則>
UIView為CALayer提供內容,以及負責處理觸摸等事件,參與響應鏈
CALayer負責顯示內容contents
二、事件傳遞與視圖響應鏈 :
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;
如果事件一直傳遞到UIAppliction還是沒處理,那就會忽略掉
三、圖像顯示原理
1.CPU:輸出位圖
2.GPU :圖層渲染,紋理合成
3.把結果放到幀緩沖區(frame buffer)中
4.再由視頻控制器根據vsync信號在指定時間之前去提取幀緩沖區的屏幕顯示內容
5.顯示到屏幕上
CPU工作
1.Layout: UI布局,文本計算
2.Display: 繪制
3.Prepare: 圖片解碼
4.Commit:提交位圖
GPU渲染管線(OpenGL)
頂點著色,圖元裝配,光柵化,片段著色,片段處理
四、UI卡頓掉幀原因
iOS設備的硬件時鐘會發出Vsync(垂直同步信號),然后App的CPU會去計算屏幕要顯示的內容,之后將計算好的內容提交到GPU去渲染。隨后,GPU將渲染結果提交到幀緩沖區,等到下一個VSync到來時將緩沖區的幀顯示到屏幕上。也就是說,一幀的顯示是由CPU和GPU共同決定的。
一般來說,頁面滑動流暢是60fps,也就是1s有60幀更新,即每隔16.7ms就要產生一幀畫面,而如果CPU和GPU加起來的處理時間超過了16.7ms,就會造成掉幀甚至卡頓。
五、滑動優化方案
CPU:把以下操作放在子線程中
1.對象創建、調整、銷毀
2.預排版(布局計算、文本計算、緩存高度等等)
3.預渲染(文本等異步繪制,圖片解碼等)
GPU:
紋理渲染,視圖混合
一般遇到性能問題時,考慮以下問題:
是否受到CPU或者GPU的限制?
是否有不必要的CPU渲染?
是否有太多的離屏渲染操作?
是否有太多的圖層混合操作?
是否有奇怪的圖片格式或者尺寸?
是否涉及到昂貴的view或者效果?
view的層次結構是否合理?
六、UI繪制原理
異步繪制:
[self.layer.delegate displayLayer: ]
代理負責生成對應的bitmap
設置該bitmap作為該layer.contents屬性的值
七、離屏渲染
On-Screen Rendering:當前屏幕渲染,指的是GPU的渲染操作是在當前用于顯示的屏幕緩沖區中進行
Off-Screen Rendering:離屏渲染,分為CPU離屏渲染和GPU離屏渲染兩種形式。GPU離屏渲染指的是GPU在當前屏幕緩沖區外新開辟一個緩沖區進行渲染操作
應當盡量避免的則是GPU離屏渲染
GPU離屏渲染何時會觸發呢?
圓角(當和maskToBounds一起使用時)、圖層蒙版、陰影,設置
layer.shouldRasterize = YES
為什么要避免GPU離屏渲染?
GPU需要做額外的渲染操作。通常GPU在做渲染的時候是很快的,但是涉及到offscreen-render的時候情況就可能有些不同,因為需要額外開辟一個新的緩沖區進行渲染,然后繪制到當前屏幕的過程需要做onscreen跟offscreen上下文之間的切換,這個過程的消耗會比較昂貴,涉及到OpenGL的pipeline跟barrier,而且offscreen-render在每一幀都會涉及到,因此處理不當肯定會對性能產生一定的影響。另外由于離屏渲染會增加GPU的工作量,可能會導致CPU+GPU的處理時間超出16.7ms,導致掉幀卡頓。所以可以的話應盡量減少offscreen-render的圖層