编写Masonry代码的正确方式:在-init还是-layoutSubViews中?二者性能有差异吗?
Masonry布局:-init vs -layoutSubViews的性能差异分析
Hey there! Great question—this is a common point of confusion when working with Auto Layout and Masonry in iOS. Let’s break down how these two approaches differ in terms of performance, and when to use each.
1. 在-init(或其变种,如-initWithFrame:、-initWithCoder:)中设置约束
- 执行时机:仅在视图初始化时执行一次,后续除非手动重新初始化视图,否则不会再次运行。
- 性能优势:约束只被添加一次,没有重复计算或冗余操作的开销。Auto Layout只需要处理这一批约束一次,后续布局计算都是基于已有的约束进行,效率很高。
- 注意事项:必须确保你要添加约束的子视图已经被添加到父视图上(即先调用
addSubview:),否则约束会因目标视图不在视图层级中而失效。只要做到这一点,这种方式是最省心且高效的。
2. 在-layoutSubViews中设置约束
- 执行时机:这个方法会被系统频繁触发——设备旋转、父视图frame改变、子视图内容更新、甚至系统触发的重绘操作,都会导致它被调用。
- 性能隐患:
- 如果每次都调用
mas_makeConstraints,会不断添加新的约束,旧约束不会自动移除,最终导致约束冲突,同时Auto Layout的布局计算会越来越慢(因为要处理越来越多的冗余约束)。 - 即使你用
mas_updateConstraints或mas_remakeConstraints,频繁执行这些操作也会增加布局计算的负担,毕竟每次调用都会触发Auto Layout的更新流程。
- 如果每次都调用
- 正确用法:只有当约束需要动态调整时(比如根据视图当前尺寸改变约束常量,或根据数据变化切换约束),才考虑在这里处理。但一定要加上条件判断,只在必要时更新约束,避免无意义的重复操作。
总结:性能差异对比
- 优先选择
-init系列方法:对于固定不变的约束,这是性能最优的方案,因为一次性完成约束设置,没有后续冗余开销。 - 谨慎使用
-layoutSubViews:仅用于动态约束场景,且必须避免重复添加约束,使用更新/重置类的API,并添加触发条件控制。
内容的提问来源于stack exchange,提问作者Leo.J
相关产品推荐
相关产品推荐

