iOS面試 -- UI視圖相關

UITableView 復用機制

為什么要用重用機制?

當UITableView滾動時,如果不用重用機制,會重復初始化原來已經有初始化過的cell,因此用重用機制會節省性能,避免出現卡頓現象

重用機制的原理

重用機制主要用到了一個可變數組visiableCells和一個可變的字典類型reusableTableCells,其中visiableCells用來存儲當前UITableView顯示的cell,reusableTableCells用來存儲已經用'identify'緩存的cell。當UITableView滾動的時候,會先在reusableTableCells中根據identify找是否有有已經緩存的cell,如果有直接用,沒有再去初始化。

數據源同步問題

  1. 并發訪問 數據拷貝
    • 并發即多個線程都可以執行同一段時間,不需要相互等待,主線程與用戶互動,子線程做所需要的網絡數據請求、數據解析及預排版等
    • 主線程事先拷貝一份數據給子線程做網絡請求、數據解析、預排版等,如果主線程有相關操作,記錄操作,在子線程完成相關操作后將這條操作,與子線程的數據進行同步,再回到主線程刷新界面
    • 缺點:需要拷貝大量數據,耗內存

2.串行訪問
- 創建一個GCD串行隊列,主線程的操作需要等待子線程操作完成
- 缺點:需要等待子線程完成,可能會耗時較長

UIView的事件傳遞以及視圖響應的機制和流程

UIView以及CALayer的關系和區別
  • 關系:
    UIView的內部包含CALayer層。創建UIView時,會自動創建一個CALyer層的對象,通過UIView的layer屬性可以訪問到。UIView需要顯示時,會調用drawRect方法進行繪制,并將所有內容繪制在自己的layer層。也就是CALayer層才有顯示功能。
  • 區別:
    UIView負責提供內容,以及負責處理觸摸等事件,參與響應鏈
    CALayer負責顯示內容contents
事件傳遞與視圖響應鏈
  • 事件的分發與傳遞

    1. 當iOS程序中發生觸摸事件,系統會將事件加入到UIApplication管理的一個任務隊列

    2. UIApplication將處于任務隊列最前端的事件向下分發。即UIWindow ->UIView

    3.UIView首先看自己是否能處理事件,觸摸點是否在自己身上。如果能,那么繼續尋找子視圖。

    5.遍歷子控件,重復以上兩步

    6.如果沒有找到,那么自己就是事件處理者

    7.如果自己不能處理,那么不做任何處理

    其中不接受處理的事件情況如下三種:
    - alpha <0.01
    - userInteractionEnabled = NO
    - hidden = YES.
    如果父視圖不接受事件處理,則子視圖也不能接收。事件只要觸摸就會產生,關鍵在于是否有合適的View處理接收事件

  • 如何尋找最合適的View呢?以下兩個方法

// 此方法返回的View是本次點擊事件需要的最佳View
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

// 判斷一個點是否落在范圍內
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event

事件傳遞給窗口或控件的后,就調用hitTest:withEvent:方法尋找更合適的view,如果子控件是合適的view,則在子控件再調用hitTest:withEvent:直到找到最合適的為止

  • 響應者鏈
    響應者鏈的傳遞方法是事件傳遞的反方法,如果所有的響應者都不處理,則事件被丟棄

圖像顯示原理(為了關于UI卡頓掉幀原因做的鋪墊 了解)

圖像顯示原理

CPU GPU通過總線連接 通過CPU進行繪圖,將位圖經由總線在合適的時機給GPU,GPU做位圖的涂層渲染和紋理合成,再放到幀緩沖區域(Frame Buffer)中, 由視頻控制器根據VSync在幀緩沖區域中提取屏幕顯示內容,顯示到手機屏幕中

圖像顯示原理

CPU
需要做Layout布局(UI布局),Display顯示(繪制 drawRect),Prepare準備工作(圖片編解碼),Commit提交(提交位圖)
GPU
需要做 頂點著色 圖源裝配 光柵化 片段著色 片段處理 再放到幀緩沖區域(Frame Buffer)

UI卡頓 掉幀的原因 以及優化方案

UI卡頓 掉幀的原因
UI卡頓掉幀的原因

保持流暢的UI交互,FPS應該保持在60,即16.7ms刷新一次頁面,如果CPU處理時間過長,導致VSync信號到來之前CPU和GPU無法完成下一幀畫面的合成,就會造成肉眼可見的卡頓

tableView的滑動優化方案
  • CPU
    對象創建、調整、銷毀
    預排版(布局計算、文本計算)
    預渲染(文本異步繪制、圖片編解碼)
    -GPU
    紋理渲染(減少不必要的離屏渲染)
    視圖混合(減輕視圖層級的復雜性)

如何具體優化呢?

  • 官方在iOS9.0后對UIImageView設置圓角進行優化,但是設置陰影依然會觸發離屏渲染
  • 圓角優化
    1.使用貝塞爾曲線UIBezierPath和Core Graphics框架畫出一個圓角
    2.使用CAShapeLayer和UIBezierPath設置圓角
  • shadow優化
    通過設置shadowPath來優化性能

其他優化方案:

  • 盡量使用不包含透明(alpha)通道的圖片資源
  • 盡量設置layer的大小值為整形值
  • 使用一張中間透明圖片蒙上去
  • 如果是本地圖:直接讓美工把圖片切成圓角進行顯示
  • 上傳圖片進行顯示,可以讓服務端處理圓角
  • 利用UIBezierPath(CoreGraphics框架)畫出來圓角圖片

Core Animation工具檢測離屏渲染

對于離屏渲染的檢測,蘋果為我們提供了一個測試工具Core Animation。可以在Xcode->Open Develeper Tools->Instruments中找到

UIView的繪制原理

離屏渲染??

離屏渲染
  • 在屏渲染 On-screen,Rendering 當前屏幕渲染
    GPU的渲染操作在當前用于顯示的屏幕緩沖區中進行
  • 離屏渲染 Off-Screen,GPU當前屏幕緩沖區之外新開辟一個緩沖區來進行渲染操作

什么是離屏渲染:
當指定了視圖的某些圖層屬性標記了不能在當前 的屏幕緩沖區中直接顯示時,則需要開辟一塊新的緩沖區進行渲染操作,即離屏渲染,需要多次切換上下文

何時會觸發離屏渲染?
  • 圓角 layer.masksToBounds = YES 和layer.cornerRadius 同時使用
  • 蒙版 layer.mask
  • 透明度 layer.allowsGroupOpacity = YES 和 layer.opacity < 1.0
  • 陰影 layer.shadow
  • 光柵化 layer.shouldRasterize=true
為什么要避免離屏渲染?

觸發離屏渲染會增加GPU的工作量,就會進一步增加CPU和GPU的工作耗時超出16.7ms,可能就會導致UI的卡頓和掉幀,所以要盡量避免

離屏渲染會創建新的渲染緩沖區,以及多次的上下文切換,將多通道的渲染結果做最終的合成,會造成額外的內存開銷

2019-11-12

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,333評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,491評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,263評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,946評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,708評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,409評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,939評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,774評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,209評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,641評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,872評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,650評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,958評論 2 373