20

我遇到了一个非常奇怪的问题,我想知道是否有人可以在这里帮助我,因为我完全迷路了。

背景:我正在开发一个层次结构相对简单的应用程序。只有几个视图控制器,但有很多高分辨率图像。它们以UIScrollView带有一些文本等的形式呈现。在纵向模式下对其进行测试时,滚动视图根本没有平滑滚动。似乎帧速率下降到大约 4-5 fps。首先,我认为这是因为高分辨率图像。

但后来我把 iPad 调到了横向模式,一切都运行得很顺利。由于我有一个单独的纵向和横向 xib 文件,我认为纵向 xib 中一定有问题。原来,没有。两者都有相同的 VC 类,因此使用相同的代码和两个 xib 几乎相同,除了视图的大小和位置。

为了缩小问题的范围,我使用 Instrument 的 TimeProfiler 来查看导致问题的原因。事实证明,TimeProfiler 显示了一些对[NSISEngine optimize](由 触发NSLayoutConstraint)的调用。在纵向模式下,通话次数更多,而且通话时间更长。在树的下方,我看到在纵向模式下[NSISEngine optimize]调用[NSISEngine fixupIntegralizationViolations],而在横向模式下却没有。

我什至从应用程序中删除了所有视图控制器,除了 rootVC 和 rootVC 提供的另一个。呈现的 vc 仅包含一些图像、按钮和一些动画。它只有一个 xib 用于两个方向,并且(与所有其他方向一样)使用自动布局进行布局。

布局在两个方向上都可以正常工作,并且没有歧义(据我所知。至少po [[UIWindow keyWindow] _autolayoutTrace]没有显示任何内容)。

我附上了vc演示过程的TimeProfile截图。一张是纵向的,一张是横向的。如您所见,在横向调用[NSISEngine optimize]只需要一毫秒,而在纵向调用则需要超过 3000 毫秒。

有谁可以告诉我这是为什么?或者也许知道我能做些什么来找出问题所在?

任何帮助将不胜感激!

谢谢

链接到更大版本的图像:链接

Instruments Timeprofiler 截图

4

3 回答 3

4

我在中等复杂的视图中遇到了同样的问题,它在非 Retina iPad 或纵向模式下的 Retina iPad 上表现良好。在 Retina 设备上的横向模式下,显示弹出框或在视图堆栈上推送另一个视图需要 10 倍的时间。我最终在视图控制器中用手动编码的 loadView 替换了 XIB 文件。这似乎已经消除了这个问题。界面生成器倾向于创建过多的约束,因此控制它是良好的自动布局性能的关键。

我还为此问题开了一张支持票。

更新:

我在我的情况中找到了原因。这是以下一组约束:

NSArray *constraints = [NSLayoutConstraint
                        constraintsWithVisualFormat : @"|[sunLabel][monLabel(==sunLabel)][tueLabel(==sunLabel)][wedLabel(==sunLabel)][thuLabel(==sunLabel)][friLabel(==sunLabel)][satLabel(==sunLabel)]|"
                        options : 0
                        metrics : nil
                        views : labelViewsDictionary];

它指定父视图中的 7 个标签都共享相同的大小,并且都扩展父视图的宽度。我相信布局的过度关系性质使自动布局适合,特别是因为父视图宽度不能被 7 整除。

为了解决这个问题,我创建了一组约束来指定每个标签的宽度并应用这些约束。当设备旋转父视图宽度时,我会返回并将约束上的常量调整为父视图宽度的 1/7。这现在表现良好,加载弹出框的过程现在需要不到 300 毫秒而不是 2000 毫秒。

于 2013-03-29T13:30:04.160 回答
3

我就这个问题提交了技术支持请求,最后得到了答案,这很可能是一个错误。已提交错误报告。希望他们能尽快修复它。如果有任何消息,我会更新这个答案。

于 2012-10-26T22:03:59.600 回答
0

我昨天在 Ipad iOS6.1 设备上遇到了同样的问题。检测应用程序发现,每次调用方法 fixupIntegralizationViolations 大约需要 300 毫秒(大约 20 次,这很多),这使得应用程序完全无用。

我的问题与 Jack Cox 的评论非常相似,但我以不同的方式解决了它。我的限制是:

@"H:|[allButton][inStoreButton(==allButton)][onlineButton(==allButton)][sortButton(50)]|"

问题是这里的 parentView 是整个 iPad 横向宽度,所以这个约束的数学是给每个按钮这个宽度:(1024-50)/3 = 324.6666667。

这在自动布局中通常不是问题,因为它会处理大浮点数并正确舍入它们,但似乎在 iPad iOS6 Landscape 中舍入此数字会触发阻塞 UI 的错误。为了解决这个问题,我所要做的就是将 sortButton 更改为 52,因此现在每个按钮的宽度为:(1024-52)/3 = 324。仅此而已。现在,每次调用 fixupIntegralizationViolations 方法大约需要 1 毫秒。

有趣的是,使用 52 在横向中给出了非十进制宽度,但在纵向中确实给出了十进制数:(768-52)/3 = 238.666667。但是,纵向似乎没有任何错误,并且自动布局正确地舍入了数字。

于 2014-05-15T15:02:21.003 回答