【问题标题】:Why using NSLayoutConstraint.activate is more efficient than .isActive = true?为什么使用 NSLayoutConstraint.activate 比 .isActive = true 更有效?
【发布时间】:2023-03-19 19:19:01
【问题描述】:

我的问题是关于约束的创建:为什么使用activate 方法创建一组稍后激活的约束比使用.isActive = true 逐个激活更有效?

激活一个直接约束,我们基本上是在改变一个属性,一个已经在我们正在修改的UIView 中实例化的变量:

@available(iOS 9.0, *)
open var topAnchor: NSLayoutYAxisAnchor { get }

但定义表明使用Array更高效:

/* Convenience method that activates each constraint in the contained array, in the same manner as setting active=YES.
This is often more efficient than activating each constraint individually. */
@available(iOS 8.0, *)
open class func activate(_ constraints: [NSLayoutConstraint])

我看不到如何创建一个已经在范围内的变量数组,然后将其传递给循环以激活它。这比启用直接约束如何更有效?

【问题讨论】:

  • 可能想看developer.apple.com/videos/play/wwdc2018/220 - 它有一些很棒的细节。
  • 为什么您的代码针对 iOS 9? (为了记录,我仍然有针对此的应用程序涉及 CoreImage。)我努力提高效率。但就 iOS(甚至 iPadOS)而言,我没有看到实际问题。硬件比那些日子好多了……你能提供更多细节吗?
  • @dfd 这个代码是我直接从定义中得到的。
  • 明白。 AutoLayout 是一种有趣的动物 - 并且文档很少。那时我会选择答案,稍后我会投票赞成。使用引擎...在可能的情况下设置isActive = true 并根据需要激活/停用其他引擎。查看任何警告,并在可能的情况下再次消除它们。最重要的是?如果它有效,它就有效。不要为小事出汗——我的意思是,与 AutoLayout 引擎打破布局中的错误约束相比,“高效”是很小的。

标签: ios swift constraints


【解决方案1】:

当您需要激活多个约束时,如果您逐个进行,AutoLayout 不知道何时“完成”激活它们。这可能会导致它在 约束之间执行一些中间计算,随后立即添加另一个约束会浪费其结果。通过一次向 AutoLayout 提供一个约束列表,它既可以确保它不会在两次激活之间执行任何中间计算,也可以更好地了解所做的更改,从而可能导致更多准确和高性能的计算。


如果你在/System/Library/PrivateFrameworks/CoreAutoLayout.framework 中使用像 Hopper 这样的反汇编程序,你可能(目前)看到:

  • +[NSAutolayoutConstraint activateConstraints:] 的实现是对私有+[NSAutolayoutConstraint _addOrRemoveConstraints:activate:] 的透传
  • +[NSAutolayoutConstraint _addOrRemoveConstraints:activate:],对于每个约束,尝试获取对约束所属的布局引擎的引用 (-[NSLayoutConstraint _layoutEngine]),并且
    • 如果它属于引擎,则通过调用引擎的-[NSISEngine withAutomaticOptimizationsDisabled:] 方法来激活或停用约束
    • 如果它还不属于引擎,它将直接激活约束

-[NSLayoutConstraint setActive:] 本身也做了大量的工作,可能会搜索其_nearestAncestorLayoutItem_findCommonAncestorOfItem:andItem: 以便插入到正确的位置。通过在禁用优化的上下文中完成这项工作,自动布局可以避免对列表中的每个约束都进行不必要的工作。


AutoLayout 必须为您的每个约束做的工作量可能会使创建一个数组来临时存储它们的成本相形见绌,尽管您可能会在实时应用中对此进行分析以查看它可能会花费您什么。

【讨论】:

    猜你喜欢
    • 2020-05-17
    • 2013-03-24
    • 1970-01-01
    • 2017-04-14
    • 1970-01-01
    • 2020-01-10
    • 1970-01-01
    • 2020-01-09
    • 1970-01-01
    相关资源
    最近更新 更多