(WWDC) 高性能AutoLayout (High Performance Auto Layout)


内容概览:

• AutoLayout在iOS 12的性能提升
• AutoLayout内部原理和直觉
• 构建高效的布局


AutoLayout在iOS 12的性能提升

灰色为iOS 11上的表现,蓝色为iOS 12上的表现。

条纹越短更好


AutoLayout内部原理与我们的直觉

假如你需要构建如下布局:



这样创建约束是不可取的,因为updateConstraints方法可能会在一秒内执行120次!


updateConstraints方法在做什么?

首先,需要介绍渲染循环(Render Loop)。也就是界面控件绘制的流程。
可以看到,渲染循环主要分为更新约束、布局、展示这三个子过程。



首先更新约束,顺序是从子视图到父视图,一直到 UIWindow,依次执行 updateConstraints() 方法。



然后是布局,顺序是从 UIWindow 开始,从父视图到子视图,依次执行 layoutSubviews() 方法。



最后是展示,顺序与布局流程相同,依次执行 draw(_ rect: CGRect) 方法。



相关的方法如下所示:

set开头的方法可以设置标记,在下一次渲染循环(Render Loop)时就会执行相应的流程。
IfNeeded结尾的方法,可以让相应的流程在当前渲染循环(Render Loop)就执行。

所以,同样地,也不要这样做!




添加 静态约束(不需要做后续的更改) 的正确方式,应该是这样:

或者,通过Xib来添加静态约束。


启用一个约束

AutoLayout内部实现原理

  1. 首先,将View放到Window上,并添加相应的约束;
  2. 布局引擎会在updateConstraints()过程中生成与约束相关的方程式;
  3. 在layoutSubviews()过程中,View会从布局引擎中取出方程式计算的结果并用于View的布局。



计算的结果,实际上就是这四个参数:minX, minY, width, height。

当约束发生变化时,布局引擎又会根据新的方程式计算新的结果,并通知View去调用父视图的setNeedsLayout()方法。


本地布局和全局布局
本地布局

全局布局(黄线对齐约束)

不相关的视图之间不要建立约束关系。
比如,上图中的text1和text3不要创建对齐的约束,这会导致AutoLayout性能下降!



添加不交互的布局时,布局的数量对布局性能的影响呈线性增长。
如果可以和直接的父视图(self.superview)或者直接父视图中的兄弟视图建立约束,就不要和其他视图建立约束,因为这样的约束性能最好。






实际上,布局引擎就是一个布局缓存和依赖记录器。

最后,后续的Instruments会增加Layout调试组件,敬请期待。
使用工具调试布局的性能问题可以让我们免于直觉的误导。


构建高效的布局

假设你需要构建如下布局:


无图状态

有图状态

单个用户头像状态



实际的效果图:



可以使用Instruments中的Layout诊断工具进行诊断:

不过,遗憾的是Xcode 10.2中并未发现此工具😂。可能还需要等到后续的Xcode版本才能用上。



仔细观察布局,对于控件1的布局,我们可以通过修改控件隐藏/显示属性来进行控制,所以只有控件2真正需要改变布局的约束。而控件2涉及到的约束其实并不多,通过两组约束就可以进行调控。


约束波动:
  • 避免移除所有约束;
  • 对于静态约束,只添加一次;
  • 只改变需要改变的约束;
  • 隐藏View,而不是removeFromSuperview();


intrinsicContentSize属性:
  • 不是所有的View都需要它;
  • 不以View作为内容的View:
    • UIImageView 返回image的size;
    • UILabel 返回text的size,所以长文本可能会造成性能问题;
  • UIView使用它来创建约束;
  • 选择性地重写来提高文本控件布局性能;
    • 直接返回文本的size,而不是让系统去计算文本的size;
    • 使用UIView.noIntrinsicMetric和约束;
override var intrinsicContentSize: CGSize {
    // 避免文本size的计算,让约束决定文本的size
    return CGSize(width: UIView.noIntrinsicMetric, height: UIView.noIntrinsicMetric)
}


systemLayoutSizeFitting(_ targetSize:)方法
  • 从布局引擎取出计算结果;
  • 在结合frame使用的时候,需要用到它。

在调用systemLayoutSizeFitting(_ targetSize:)方法时,具体执行流程如下:

  1. 创建布局引擎;
  2. 添加约束;
  3. 计算布局;
  4. 顶部View的Size被返回;
  5. 布局引擎被废弃;

所以,使用这个方法前需要考虑性能问题,毕竟每次调用都会创建一个新的布局引擎。





参考文章:
High Performance Auto Layout




转载请注明出处,谢谢~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343