iOS面試題---UI相關(guān):事件傳遞,圖像顯示,性能優(yōu)化,離屏渲染

  • UIView與CALayer
  • 事件傳遞與視圖響應(yīng)鏈
  • 圖像顯示原理
  • UI卡頓掉幀原因
  • 滑動(dòng)優(yōu)化方案
  • UI繪制原理
  • 離屏渲染

一、UIView與CALayer

image

<單一職責(zé)原則>
UIView為CALayer提供內(nèi)容,以及負(fù)責(zé)處理觸摸等事件,參與響應(yīng)鏈
CALayer負(fù)責(zé)顯示內(nèi)容contents

二、事件傳遞與視圖響應(yīng)鏈 :

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;

image
image

如果事件一直傳遞到UIAppliction還是沒(méi)處理,那就會(huì)忽略掉

三、圖像顯示原理

image

1.CPU:輸出位圖
2.GPU :圖層渲染,紋理合成
3.把結(jié)果放到幀緩沖區(qū)(frame buffer)中
4.再由視頻控制器根據(jù)vsync信號(hào)在指定時(shí)間之前去提取幀緩沖區(qū)的屏幕顯示內(nèi)容
5.顯示到屏幕上

image

CPU工作
1.Layout: UI布局,文本計(jì)算
2.Display: 繪制
3.Prepare: 圖片解碼
4.Commit:提交位圖

GPU渲染管線(xiàn)(OpenGL)
頂點(diǎn)著色,圖元裝配,光柵化,片段著色,片段處理

四、UI卡頓掉幀原因

image

iOS設(shè)備的硬件時(shí)鐘會(huì)發(fā)出Vsync(垂直同步信號(hào)),然后App的CPU會(huì)去計(jì)算屏幕要顯示的內(nèi)容,之后將計(jì)算好的內(nèi)容提交到GPU去渲染。隨后,GPU將渲染結(jié)果提交到幀緩沖區(qū),等到下一個(gè)VSync到來(lái)時(shí)將緩沖區(qū)的幀顯示到屏幕上。也就是說(shuō),一幀的顯示是由CPU和GPU共同決定的。
一般來(lái)說(shuō),頁(yè)面滑動(dòng)流暢是60fps,也就是1s有60幀更新,即每隔16.7ms就要產(chǎn)生一幀畫(huà)面,而如果CPU和GPU加起來(lái)的處理時(shí)間超過(guò)了16.7ms,就會(huì)造成掉幀甚至卡頓。

五、滑動(dòng)優(yōu)化方案
CPU:把以下操作放在子線(xiàn)程中
1.對(duì)象創(chuàng)建、調(diào)整、銷(xiāo)毀
2.預(yù)排版(布局計(jì)算、文本計(jì)算、緩存高度等等)
3.預(yù)渲染(文本等異步繪制,圖片解碼等)

GPU:
紋理渲染,視圖混合

一般遇到性能問(wèn)題時(shí),考慮以下問(wèn)題:
是否受到CPU或者GPU的限制?
是否有不必要的CPU渲染?
是否有太多的離屏渲染操作?
是否有太多的圖層混合操作?
是否有奇怪的圖片格式或者尺寸?
是否涉及到昂貴的view或者效果?
view的層次結(jié)構(gòu)是否合理?

六、UI繪制原理

image
image

異步繪制:
[self.layer.delegate displayLayer: ]
代理負(fù)責(zé)生成對(duì)應(yīng)的bitmap
設(shè)置該bitmap作為該layer.contents屬性的值

image

七、離屏渲染

On-Screen Rendering:當(dāng)前屏幕渲染,指的是GPU的渲染操作是在當(dāng)前用于顯示的屏幕緩沖區(qū)中進(jìn)行
Off-Screen Rendering:離屏渲染,分為CPU離屏渲染和GPU離屏渲染兩種形式。GPU離屏渲染指的是GPU在當(dāng)前屏幕緩沖區(qū)外新開(kāi)辟一個(gè)緩沖區(qū)進(jìn)行渲染操作
應(yīng)當(dāng)盡量避免的則是GPU離屏渲染

GPU離屏渲染何時(shí)會(huì)觸發(fā)呢?
圓角(當(dāng)和maskToBounds一起使用時(shí))、圖層蒙版、陰影,設(shè)置

layer.shouldRasterize = YES

為什么要避免GPU離屏渲染?
GPU需要做額外的渲染操作。通常GPU在做渲染的時(shí)候是很快的,但是涉及到offscreen-render的時(shí)候情況就可能有些不同,因?yàn)樾枰~外開(kāi)辟一個(gè)新的緩沖區(qū)進(jìn)行渲染,然后繪制到當(dāng)前屏幕的過(guò)程需要做onscreen跟offscreen上下文之間的切換,這個(gè)過(guò)程的消耗會(huì)比較昂貴,涉及到OpenGL的pipeline跟barrier,而且offscreen-render在每一幀都會(huì)涉及到,因此處理不當(dāng)肯定會(huì)對(duì)性能產(chǎn)生一定的影響。另外由于離屏渲染會(huì)增加GPU的工作量,可能會(huì)導(dǎo)致CPU+GPU的處理時(shí)間超出16.7ms,導(dǎo)致掉幀卡頓。所以可以的話(huà)應(yīng)盡量減少offscreen-render的圖層

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容