草庐IT

纵向模式下的 iOS 自动布局性能问题。 [NSISEngine优化]

coder 2023-07-25 原文

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

上下文: 我正在开发一个层次结构相对简单的应用程序。只有几个 View Controller ,但有很多高分辨率图像。它们显示在带有一些文本等的 UIScrollView 中。在纵向模式下测试时, ScrollView 根本无法流畅滚动。帧率似乎下降到大约 4-5 fps。一开始我以为是因为高分辨率图像。

但后来我将 iPad 调成横屏模式,一切都运行得很顺利。由于我有一个单独的 xib 文件用于纵向和横向,我认为 portrait-xib 中一定有问题。事实证明,没有。两者都具有相同的 VC 类,因此使用相同的代码并且两个 xib 几乎相同,除了 View 的大小和位置。

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

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

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

我附上了vc演示过程的TimeProfile截图。一种用于人像,一种用于风景。如您所见,横向调用 [NSISEngine optimize] 只需要一毫秒,而纵向调用则需要 3000 多毫秒。

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

如有任何帮助,我们将不胜感激!

谢谢

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

最佳答案

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

我还就这个问题开了一个支持票。

更新:

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

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

它指定父 View 中的 7 个标签都具有相同的大小,并且都扩展了父 View 的宽度。我认为布局的过度相关性导致自动布局适合,特别是因为父 View 宽度不能被 7 整除。

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

关于纵向模式下的 iOS 自动布局性能问题。 [NSISEngine优化],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12945746/

有关纵向模式下的 iOS 自动布局性能问题。 [NSISEngine优化]的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  3. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  4. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  5. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  6. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  7. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  8. ruby - 是否有用于序列化和反序列化各种格式的对象层次结构的模式? - 2

    给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最

  9. ruby - nanoc 和多种布局 - 2

    是否可以为特定(或所有)项目使用多个布局?例如,我有几个项目,我想对其应用两种不同的布局。一个是绿色的,一个是蓝色的(但是)。我想将它们编译到我的输出目录中的两个不同文件夹中(例如v1和v2)。我一直在玩弄规则和编译block,但我不知道这是怎么回事。因为,每个项目在编译过程中只编译一次,我不能告诉nanoc第一次用layout1编译,第二次用layout2编译。我试过这样的东西,但它导致输出文件损坏。compile'*'doifitem.binary?#don’tfilterbinaryitemselsefilter:erblayout'layout1'layout'layout2'

  10. ruby-on-rails - 从应用程序中自定义文件夹内的命名空间自动加载 - 2

    我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty

随机推荐