setNeedsLayout vs layoutIfNeed

1,094 阅读1分钟

深入理解代替单纯记忆

  • setNeedsLayout会对当前视图做标记,在下次update cycle到来时,会对当前视图进行重新布局,layoutSubview会被执行,但当前视图的子视图的layoutSubview并不一定执行
  • setNeedsLayout只是做了个标记,并非立即进行布局,而是等待下次update cycle到来
  • layoutIfNeed则是对当前视图进行立即布局,当然,并不一定会真正执行布局过程,内部要检查视图是否有被做过修改,比如frame或其他属性有没有被修改过。如果符合重新布局条件,会触发立即布局,一个典型例子就是,当设置了autolayout约束时,立即执行layoutIfNeed,约束导致的最终frame会被立即计算出来
  • 显然,setNeedsLayout对性能更友好

setNeedsLayout何时用

这是个好问题,我查了些资料没找到很好的答案,姑且来猜测一下吧

官方对setNeedsLayout的说明中有这么一句话

Because this method does not force an immediate update, but instead waits for the next update cycle, you can use it to invalidate the layout of multiple views before any of those views are updated. This behavior allows you to consolidate all of your layout updates to one update cycle, which is usually better for performance.

翻译过来就是,当需要对多个视图做重新布局时,用该方法,能够将多个视图的布局合并到一个update cycle中,会有更好的性能

一个小技巧

因为layoutIfNeed并不一定会触发当前视图的layoutSubviews方法,若想立即让layoutSubviews执行怎么办呢?

[view setNeedsLayout];
[view layoutIfNeed];

参考