Auto Layout生命周期

Auto Layout ,是蘋果公司提供的一個基于約束布局,動態(tài)計算視圖大小和位置的庫,蘋果公司早在 iOS 6 系統(tǒng)時就引入了 Auto Layout,并且已經(jīng)集成到了 Xcode 開發(fā)環(huán)境里。

那么,Auto Layout 到底是如何實現(xiàn)自動布局的,這種布局算法會影響性能嗎?

Cassowary 算法

Cassowary 能夠有效解析線性等式系統(tǒng)和線性不等式系統(tǒng),用來表示用戶界面中那些相等關(guān)系和不等關(guān)系?;诖耍珻assowary 開發(fā)了一種規(guī)則系統(tǒng),通過約束來描述視圖間的關(guān)系。約束就是規(guī)則,這個規(guī)則能夠表示出一個視圖相對于另一個視圖的位置。

由于 Cassowary 算法讓視圖位置可以按照一種簡單的布局思路來寫,這些簡單的相對位置描述可以在運行時動態(tài)地計算出視圖具體的位置。視圖位置的寫法簡化了,界面相關(guān)代碼也就更易于維護。蘋果公司也是看重了這一點,將其引入到了自己的系統(tǒng)中。

Cassowary 算法由 Alan Borning、Kim Marriott、Peter Stuckey 等人在“Solving Linear Arithmetic Constraints for User Interface Applications”論文中提出的,為了能方便開發(fā)者更好地理解 這個算法,并將其運用到更多的開發(fā)語言中,作者還將代碼發(fā)布到了他們搭建的 Cassowary 網(wǎng)站上。

由于 Cassowary 算法本身的先進性,更多的開發(fā)者將 Cassowary 運用到了各個開發(fā)語言中,比如 JavaScript、.NET、Java、Smalltalk、C++ 都有對應(yīng)的庫。

Auto Layout 的生命周期

Auto Layout 不只有布局算法 Cassowary,還包含了布局在運行時的生命周期等一整套布局引擎系統(tǒng)\color{red}{Layout Engine},用來統(tǒng)一管理布局的創(chuàng)建、更新和銷毀,是 Auto Layout 的核心,主導(dǎo)著整個界面布局。

每個視圖在得到自己的布局之前,Layout Engine 會將視圖、約束、優(yōu)先級、固定大小通過計算轉(zhuǎn)換成最終的大小和位置。

在 Layout Engine 里,每當(dāng)約束發(fā)生變化,就會觸發(fā) Deffered Layout Pass,完成后進入監(jiān)聽約束變化的狀態(tài)。當(dāng)再次監(jiān)聽到約束變化,即進入下一輪循環(huán)中。整個過程如下圖所示:

Constraints Change
表示的就是約束變化,添加、刪除視圖時會觸發(fā)約束變化。Activating 或 Deactivating,設(shè)置 Constant 或 Priority 時也會觸發(fā)約束變化。Layout Engine 在碰到約束變化后會重新計算布局,獲取到布局后調(diào)用 superview.setNeedLayout(),然后進入 Deferred Layout Pass。

Deferred Layout Pass
主要作用是做容錯處理。如果有些視圖在更新約束時沒有確定或缺失布局聲明的話,會先在這里做容錯處理。接下來,Layout Engine 會從上到下調(diào)用 layoutSubviews(),通過 Cassowary 算法計算各個子視圖的位置,算出來后將子視圖的 frame 從 Layout Engine 里拷貝出來。在這之后的處理,就和手寫布局的繪制、渲染過程一樣了。

使用 Auto Layout 和手寫布局的區(qū)別,就是多了布局上的這個計算過程

觸發(fā)約束變化 —> Layout Engine就需要重新計算布局,會先獲取到當(dāng)前的布局,調(diào)用SuperView.SetNeedLayout() —> Deffered Layout Pass進行監(jiān)聽 —> Layout Engine 從上到下調(diào)用LayoutSubViews(),通過Cassowary算法計算各個子視圖的位置,算出來后將子視圖的Frame從Layout Engine里拷貝出來 —> 和手寫布局的繪制、渲染一樣。

Auto Layout 性能問題


上圖是 WWDC 2018 中 202 Session 里講到的 Auto Layout 在 iOS 12 中優(yōu)化后的表現(xiàn)。可以看到,優(yōu)化后的性能,已經(jīng)基本和手寫布局一樣可以達到性能隨著視圖嵌套的數(shù)量呈線性增長了。而在此之前的 Auto Layout,視圖嵌套的數(shù)量對性能的影響是呈指數(shù)級增長的。

iOS 12 之前,很多約束變化時都會重新創(chuàng)建一個計算引擎 NSISEnginer 將約束關(guān)系重新加進來,然后重新計算。結(jié)果就是,涉及到的約束關(guān)系變多時,新的計算引擎需要重新計算,最終導(dǎo)致計算量呈指數(shù)級增加。

iOS12 的 Auto Layout 更多地利用了 Cassowary 算法的界面更新策略,使其真正完成了高效的界面線性策略計算。

03 | Auto Layout 是怎么進行自動布局的,性能如何?
參考鏈接:https://github.com/ming1016/study/wiki/深入剖析Auto-Layout,分析iOS各版本新增特性

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

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