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),用來統(tǒng)一管理布局的創(chuàng)建、更新和銷毀,是
Auto Layout 的核心,主導(dǎo)著整個界面布局。
每個視圖在得到自己的布局之前,Layout Engine 會將視圖、約束、優(yōu)先級、固定大小通過計算轉(zhuǎ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各版本新增特性