由于自动布局和大量子视图,解散VC非常慢

时间:2013-11-19 07:54:35

标签: ios objective-c uiviewcontroller autolayout nslayoutconstraint

我有一个滚动视图,其中包含大量子视图,由于我不会进入的原因,我选择了cell重新使用和UITableView。它运行良好,在填充视图时保存一点初始主线程滞后。但是,每次VC "on top"被解雇(e.g. after presenting a modal overtop)时,都会有明显的延迟(2-3秒)。我通过探查器运行它,堆栈跟踪深入研究了IOS / Autolayout,如附图中所示。

代码似乎进入了  NSLayoutConstraint("+0x06 calll "-[NSLayoutConstraint _addToEngine:]+0x0b")

我有什么办法可以绕过这种明显的限制重新应用吗?

dat stack

1 个答案:

答案 0 :(得分:13)

为什么滚动视图的性能很差

通过查看跟踪,问题的根源在转换回来时开始:您在-[UITransitionView transition:fromView:toView:removeFromView:]中花费的时间是80%以上。此方法会立即将您转换回的视图添加回视图层次结构(跟随-addSubview:调用),这需要完整的自动布局传递。

我不知道有什么方法可以强制普通的iOS视图控制器转换系统在后台保持旧视图,可以这么说,以避免这种自动布局通过。 (如果多个视图在屏幕外叠加并开始引起内存压力,这种方法实际上可能会遇到一系列问题。)

加速现有结构中的自动布局

尽管如此,您仍可以尝试以两种方式优化自动布局传递。首先,重新编辑滚动视图以减少子视图。 Apple的开发人员技术支持有时也建议扁平化您的视图层次结构;导致自动布局执行较少的递归有时会有所帮助。 (例如,参见Florian KuglerMartin Pilkington执行的性能测试。)

您还应始终确保在层次结构中最深的可能视图上安装约束,同时仍然在与其相关的两个视图的共同祖先上。例如,如果视图A具有子视图B和C,则您希望约束仅引用视图C上安装的视图C,而不是视图A;但是,需要在A上存在与B和C相关的约束。这是所有自动布局工作的良好指导,而不仅仅是在这种特殊情况下;层次结构中安装的约束越深,底层求解器在任何特定级别上工作的速度就越快。

转换方法

UITableView能够通过在Auto Layout系统中提供一种中断来避免这个问题:表视图可以使用约束正确定位,然后使用自己的委托方法(例如-tableView:heightForRowAtIndexPath:)和一些内部布局魔术为每个单元格单独运行自动布局,而不需要一次性布局整个视图。常规UIScrollViews没有这种优化的优势。

我知道你说你有理由不在这里采用UITableView,但你可能会考虑重新审视这些原因。从切换到UITableView并实现委托方法-tableView:estimatedHeightForRowAtIndexPath:,您可以看到一些非常显着的速度改进,它允许您在视图加载时短路大量的自动布局计算并将它们推迟到您即将到来的那一点。在屏幕上滚动新单元格。在这方面已经进行了一些相当重要的实验,here on StackOverflow和社区中的其他人。 (快速搜索“UITableView自动布局高度”将会产生数十个结果。)

祝你好运!