简而言之:
通常,水平约束方程和垂直约束方程是独立的,但一个宽高比约束将两个维度链接起来,将两个较小的线性方程组合并成一个大的方程组。从我的理解来看,这两个较小的方程组应该比组合后的大方程组更容易解决,因此,我预计宽高比约束会降低性能。然而,对每个维度进行100次约束视图的简单测试显示性能没有差异。为什么?
问题详情:
约束是线性方程
在自动布局中,每个布局约束都是一个线性方程:
view2.attribute = multiplier * view1.attribute + constant
当所有约束条件仅有一个解时,给出了一个明确且不冲突的布局。
在方法layoutSubviews()
中,系统会“解析”约束条件,即从这些约束条件计算出所有子视图的框架。任务是解决线性方程组,可以通过应用高斯算法来完成。
x和y:两个独立的方程集
只要没有涉及纵横比约束,水平和垂直维度就相互独立。因此,水平约束有一个h线性方程组,垂直约束有一个v线性方程组。这些可以分别解决。
然而,将纵横比约束添加到视图中会链接两个维度。系统不再有两个独立的线性方程组,而是必须解决一个更大的h+v线性方程组。
解决线性方程组的复杂度
由于解决一组n个线性方程的复杂度在O(n²)和O(n³)之间,取决于算法,因此解决具有h和v方程的两个系统比解决具有h+v方程的一个系统要更快。因此,我预计只要存在至少一个纵横比约束条件,解决约束条件(即layoutSubviews()方法)的过程就会明显变长。为了弄清楚这一点,我创建了一个空样本项目,在水平和垂直轴上添加了100个视图,并适当地约束它们。然后我测量了布局过程的时间:
override func layoutSubviews() {
let t1 = mach_absolute_time()
super.layoutSubviews()
let t2 = mach_absolute_time()
print(t2 - t1)
}
然后我用一个宽高比约束替换了其中一个垂直约束,然后再次测量时间。结果几乎相同。 这是我不理解的部分。
为什么宽高比约束不会对布局性能产生不良影响?
以下是我创建和约束的视图设置。 为了更好的可视性,屏幕截图仅显示每个方向上的20个视图,而不是我测量时间时使用的100个视图。
view.width = view.height
约束。顶部行中的所有视图都具有equalHeight
约束,左侧列中的所有视图都具有equalWidth
约束。 - Mischa