2020 最新iOS面試題之視圖&圖形(附答案)

前言

本篇我們來講一下 【iOS面試題的視圖&圖形】相關(guān)的問題.

視圖&圖像相關(guān)

主要問題列表如下:

  1. AutoLayout的原理,性能如何
  2. UIView & CALayer的區(qū)別
  3. 事件響應(yīng)鏈
  4. drawrect & layoutsubviews調(diào)用時(shí)機(jī)
  5. UI的刷新原理
  6. 隱式動(dòng)畫 & 顯示動(dòng)畫區(qū)別
  7. 什么是離屏渲染
  8. imageName&imageWithContentsOfFile區(qū)別
  9. 多個(gè)相同的圖片,會(huì)重復(fù)加載嗎
  10. 圖片是什么時(shí)候解碼的,如何優(yōu)化
  11. 圖片渲染怎么優(yōu)化
  12. 如果GPU的刷新率超過了iOS屏幕60Hz刷新率是什么現(xiàn)象,怎么解決

1.AutoLayout的原理,性能如何?

AutoLayout的原理

來歷 一般大家都會(huì)認(rèn)為Auto Layout這個(gè)東西是蘋果自己搞出來的,其實(shí)不然,早在1997年Alan Borning, Kim Marriott, Peter Stuckey等人就發(fā)布了《Solving Linear Arithmetic Constraints for User Interface Applications》論文(論文地址:http://constraints.cs.washington.edu/solvers/uist97.html)提出了在解決布局問題的Cassowary constraint-solving算法實(shí)現(xiàn),并且將代碼發(fā)布在他們搭建的Cassowary網(wǎng)站上http://constraints.cs.washington.edu/cassowary/。后來更多開發(fā)者用各種語言來寫Cassowary,比如說pybee用python寫的https://github.com/pybee/cassowary。自從它發(fā)布以來JavaScript,.NET,JAVA,Smalltall和C++都有相應(yīng)的庫。2011年蘋果將這個(gè)算法運(yùn)用到了自家的布局引擎中,美其名曰Auto Layout。

論文下載鏈接比較慢,我下載了一份Cassowary原文放到了我的博客 大家可以自由下載.

AutoLayout的原理就是用Cassowary算法來將布局問題抽象成線性不等式,并分解成多個(gè)位置間的約束
因?yàn)槎嗔擞?jì)算視圖大小frame的過程,所以性能肯定沒有指定Frame坐標(biāo)要快.

詳細(xì)的原理以及高階原理請參考戴銘老師的文章 戴銘老師寫的 深入剖析Auto Layout,分析iOS各版本新增特性

性能如何?

下面是WWDC2018 High Performance Auto Layout中對(duì)比的iOS12和iOS11下分別使用自動(dòng)布局的性能對(duì)比現(xiàn)場.

經(jīng)過實(shí)驗(yàn)得出如下圖標(biāo)結(jié)論:

iOS12之前,視圖嵌套的數(shù)量對(duì)性能的影響是呈指數(shù)級(jí)增長的,而iOS12優(yōu)化之后對(duì)性能的影響是線性增長,對(duì)性能消耗不大。

無論如何優(yōu)化也肯定不如CGRectFrame那樣的設(shè)置更加直接,性能更好.

2.UIView & CALayer的區(qū)別

區(qū)別 UIView CALayer
繼承父類 UIView:UIResponder:NSObject CALayer:NSObject
用途 可以處理觸摸事件 不處理用戶的交互,不參與響應(yīng)事件傳遞
兩者關(guān)系 有一個(gè)CALayer成員變量 eg: view.layer 是UIView的成員變量
分工 處理交互層事件并包裝各種圖形的簡單設(shè)置 底層渲染圖形,支持動(dòng)畫

3.事件響應(yīng)鏈

下面這篇文章我已經(jīng)在前幾篇將runloop的時(shí)候提了不止一次,前列建議閱讀,快手的同事大部分都以這個(gè)理解為標(biāo)準(zhǔn)

iOS觸摸事件全家桶

4. drawrect & layoutsubviews調(diào)用時(shí)機(jī)

layoutSubviews:(相當(dāng)于layoutSubviews()函數(shù))在以下情況下會(huì)被調(diào)用:

  1. init初始化不會(huì)觸發(fā)layoutSubviews。
  2. addSubview會(huì)觸發(fā)layoutSubviews。
  3. 設(shè)置view的Frame會(huì)觸發(fā)layoutSubviews (frame發(fā)生變化觸發(fā))。
  4. 滾動(dòng)一個(gè)UIScrollView會(huì)觸發(fā)layoutSubviews。
  5. 旋轉(zhuǎn)Screen會(huì)觸發(fā)父UIView上的layoutSubviews事件。
  6. 改變一個(gè)UIView大小的時(shí)候也會(huì)觸發(fā)父UIView上的layoutSubviews事件。
  7. 直接調(diào)用setLayoutSubviews。

drawrect:(drawrect()函數(shù))在以下情況下會(huì)被調(diào)用:

  1. drawrect:是在UIViewController的loadView:ViewDidLoad:方法之后調(diào)用.
  2. 當(dāng)我們調(diào)用[UIFont的 sizeToFit]后,會(huì)觸發(fā)系統(tǒng)自動(dòng)調(diào)用drawRect:
  3. 當(dāng)設(shè)置UIView的contentMode或者Frame后會(huì)立即觸發(fā)觸發(fā)系統(tǒng)調(diào)用drawRect:
  4. 直接調(diào)用setNeedsDisplay設(shè)置標(biāo)記 或setNeedsDisplayInRect:的時(shí)候會(huì)觸發(fā)drawRect:

知識(shí)點(diǎn)擴(kuò)充: 當(dāng)我們操作drawRect方法的時(shí)候?qū)嶋H是在操作內(nèi)存中存放視圖的backingStore區(qū)域,用于后續(xù)圖形的渲染操作,如果不理解可以看下UIView的渲染過程.

5.UI的刷新原理

這個(gè)問題我不知道問的是不是iOS離屏渲染過程,我來簡單的回到一下這個(gè)吧

iOS 的MainRunloop 是一個(gè)60fps 的回調(diào),也就是說16.7ms(毫秒)會(huì)繪制一次屏幕在這過程中要完成以下的工作:

  • view的緩沖區(qū)創(chuàng)建
  • view內(nèi)容的繪制(如果重寫了 drawRect)
  • 接收和處理系統(tǒng)的觸摸事件

我們看到的UI圖形實(shí)際上是CPU和GPU不斷配合工作的結(jié)果.經(jīng)過UIView的渲染過程 后我們的UI會(huì)不間斷的接收系統(tǒng)圖給我們的事件.

由于主線程的runloop 一直在回調(diào),我們的UI就得到了刷新的窗口,是渲染還是處理事件都是因?yàn)閞unloop不斷工作的結(jié)果.前幾篇我們學(xué)過 main線程的runloop默認(rèn)是啟動(dòng)的.因?yàn)槲覀冺憫?yīng)交互.

不知道我這樣回答是否滿足這個(gè)問題的答案.如果回答的不對(duì)煩請下方評(píng)論區(qū)留言 告知我將持續(xù)改進(jìn).

6.隱式動(dòng)畫 & 顯示動(dòng)畫區(qū)別

隱式動(dòng)畫一直存在 如需關(guān)閉需設(shè)置
顯式動(dòng)畫是不存在,如需顯式 要開啟

只需要觀察動(dòng)畫執(zhí)行完成的結(jié)果 比如: 一個(gè)簡單UIView的frame移動(dòng) 如果從A點(diǎn)移動(dòng)到B點(diǎn) 移動(dòng)完成 回到原始位置就是隱式動(dòng)畫

Core Animation 是顯式動(dòng)畫.因?yàn)樗瓤梢灾苯訉?duì)其layer屬性做動(dòng)畫,也可以覆蓋默認(rèn)的圖層行為.

7.imageName&imageWithContentsOfFile區(qū)別

區(qū)別 UIView imageWithContentsOfFile
不同點(diǎn) 會(huì)圖片緩存到內(nèi)存中 無緩存

8.什么是離屏渲染

iOS離屏渲染的深入研究

9.多個(gè)相同的圖片,會(huì)重復(fù)加載嗎

不會(huì),GPU有 像素點(diǎn)緩存的mask.

10.圖片是什么時(shí)候解碼的,如何優(yōu)化

是加載到內(nèi)存中,從UIImge->CGImage->CGImageSourceCreateWithData(data) 創(chuàng)建ImageSource變成bitmap位圖,這些工作都是CoreAnimation在圖片被加載到內(nèi)存中存在在backingStore里,送給GPU流水線處理之前被解碼.

如何優(yōu)化

自己手動(dòng)操作圖片的編碼API

CGImageSource開頭的哪些,根據(jù)合理利用時(shí)機(jī)和操作系統(tǒng)資源調(diào)整出一套緩存小加載快的庫.

參考PINRemoteImage或者YYWebImage開源

11.圖片渲染怎么優(yōu)化

可以從陰影,圓角入手.幀率,電量,圖片的鋸齒等等.

iOS開發(fā)-視圖渲染與性能優(yōu)化

12.如果GPU的刷新率超過了iOS屏幕60Hz刷新率是什么現(xiàn)象,怎么解決

現(xiàn)象是 圖形清晰,場景逼真,但是一般arm芯片的GPU 刷新超過60Hz一定會(huì)超級(jí)費(fèi)電,手機(jī)發(fā)熱導(dǎo)致降頻.FPS降低,因?yàn)榈湍芎碾娏坎蛔?無法支持GPU高刷新率

解決辦法只能用xcode自帶工具檢測,看渲染過程哪里可以優(yōu)化.

總結(jié)

簡單回答了一些圖形相關(guān)的問題,大部分都是iOS離屏渲染,這個(gè)地方大家要認(rèn)真學(xué)習(xí).很多資料看起來比較耗時(shí).


推薦文集

收錄:原文地址

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

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

  • iOS面試題目100道 1.線程和進(jìn)程的區(qū)別。 進(jìn)程是系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位,線程是進(jìn)程的一個(gè)實(shí)體,...
    有度YouDo閱讀 30,120評(píng)論 8 137
  • Swift 1> Swift和OC的區(qū)別 1.1> Swift沒有地址/指針的概念 1.2>泛型 1.3>類型嚴(yán)謹(jǐn)...
    紫色冰雨閱讀 611評(píng)論 0 1
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,619評(píng)論 1 32
  • 金三銀四,相信最近很多人都在跳槽。那么面試題自然還是要看下的,在這我就把我手里收集到的面試題(朋友面試,網(wǎng)上收集等...
    lp_lp閱讀 1,692評(píng)論 0 22
  • 漸變的面目拼圖要我怎么拼? 我是疲乏了還是投降了? 不是不允許自己墜落, 我沒有滴水不進(jìn)的保護(hù)膜。 就是害怕變得面...
    悶熱當(dāng)乘涼閱讀 4,462評(píng)論 0 13

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