iOS高級開發工程師面試——關于優化
- 一、TableView 有什么好的性能優化方案?
- 二、界面卡頓和檢測你都是怎么處理?
- 三、談談你對離屏渲染的理解?
- 四、如何降低APP包的大小?
- 五、日常如何檢查內存泄露?
- 六、APP啟動時間應從哪些方面優化?
一、TableView 有什么好的性能優化方案?
Tableview 懶加載、Cell 復用
高度緩存
(因為 heightForRowAtIndexPath: 是調用最頻繁的方法)
- 當 cell 的行高固定時,使用固定行高 self.tableView.rowHeight = xxx;
- 當 cell 的行高是不固定時,根據內容進行計算后緩存起來使用。第一次肯定會計算,后續使用緩存時就避免了多次計算;高度的計算方法通常寫在自定義的cell中,調用時,既可以在設置
cell 高的代理方法中使用,也可以自定義的 model 中使用(且使用時,使用get方法處理)。
數據處理
- 使用正確的數據結構來存儲數據;
- 數據盡量采用局部的 section,或 cellRow 的刷新,避免 reloadData;
- 大量數據操作時,使用異步子線程處理,避免主線程中直接操作;
- 緩存請求結果。
異步加載圖片
:SDWebImage 的使用
使用異步子線程處理,然后再返回主線程操作;
圖片緩存處理,避免多次處理操作;
圖片圓角處理時,設置 layer 的 shouldRasterize (英[?r?st?ra?z])屬性為 YES,可以將負載轉移給 CPU。
- 按需加載內容
滑動操作時,只顯示目標范圍內的 Cell 內容,顯示過的超出目標范圍內之后則進行清除;
滑動過程中,不加載顯示圖片,停止時才加載顯示圖片。
- 視圖層面
(1)減少 subviews 的數量,自定義的子視圖可以整合在形成一個整體的就整合成一個整體的子視圖;
(2)使用 drawRect 進行繪制(即將 GPU 的部分渲染轉接給 CPU ),或 CALayer 進行文本或圖片的繪制。在實現 drawRect方法的時候注意減少多余的繪制操作,它的參數 rect 就是我們需要繪制的區域,在 rect范圍之外的區域我們不需要進行繪制,否則會消耗相當大的資源;
(3)異步繪制,且設置屬性self.layer.drawsAsynchronously = YES;(遇到復雜界面,遇到性能瓶頸時,可能就是突破口);
(4)定義一種(盡量少)類型的 Cell 及善用 hidden 隱藏(顯示) subviews;
(5)盡量使所有的 view 的opaque 屬性為 YES,包括 cell 自身,以提高視圖渲染速度(避免無用的 alpha 通道合成,降低 GPU 負載);
(6)避免漸變,圖片縮放的操作;
(7)使用 shadowPath 來畫陰影;
(8)盡量不使用cellForRowAtIndexPath: ,如果你需要用到它,只用一次然后緩存結果;
(9)cellForRowAtIndexPath不要做耗時操作:如不讀取文件 / 寫入文件;盡量少用 addView 給 Cell 動態添加 View,可以初始化時就添加,然后通過hide 來控制是否顯示;
(10)我們在 Cell上添加系統控件的時候,實際上系統都會調用底層的接口進行繪制,大量添加控件時,會消耗很大的資源并且也會影響渲染的性能。當使用默認UITableViewCell 并且在它的 ContentView 上面添加控件時會相當消耗性能。所以目前最佳的方法還是繼承UITableViewCell,并重寫 drawRect 方法;
(11)當我們需要圓角效果時,可以使用一張中間透明圖片蒙上去使用ShadowPath 指定 layer 陰影效果路徑使用異步進行 layer 渲染(Facebook 開源的異步繪制框AsyncDisplayKit )設置 layer 的 opaque 值為 YES減少復雜圖層合成盡量使用不包含透明(alpha)通道的圖片資源盡量設置 layer的大小值為整形值直接讓美工把圖片切成圓角進行顯示,這是效率最高的一種方案很多情況下用戶上傳圖片進行顯示,可以讓服務端處理圓角使用代碼手動生成圓角 Image 設置到要顯示的 View 上,利用 UIBezierPath ( CoreGraphics 框架)畫出來圓角圖片。
二、界面卡頓和檢測你都是怎么處理?
卡頓原因:
在一個VSync
內GPU和CPU的協作,未能將渲染任務完成放入到幀緩沖區,視頻控制器去緩沖區拿數據的時候是空的,所以卡幀。
卡頓優化:
-
圖片等大文件IO緩存
-
耗時操作放入子線程
-
提高代碼執行效率(JSON to Model的方案,鎖的使用等,減少循環,UI布局frame子線程預計算)
-
UI減少全局刷新,盡量使用局部刷新