Подтвердить что ты не робот

Проблема с автоопределением iOS в портретном режиме. [NSISEngine optimize]

Я столкнулся с очень странной проблемой, и мне было интересно, может ли кто-нибудь помочь мне, так как я полностью потерялся.

Контекст: Я разрабатываю приложение с относительно простой иерархией. Просто несколько контроллеров просмотра, но довольно много изображений с высоким разрешением. Они представлены в формате UIScrollView с некоторым текстом и т.д. При тестировании в портретном режиме прокрутка не прокручивалась плавно. Казалось, что частота кадров упала примерно до 4-5 кадров в секунду. Сначала я подумал, что это из-за изображений с высоким разрешением.

Но затем я превратил iPad в альбомный режим, и все прошло гладко. Поскольку у меня есть отдельный xib файл для портрета и пейзажа, я думал, что в портрете-xib должна быть проблема. Оказалось, не было. Оба имеют одинаковый VC-класс и поэтому используют один и тот же код, и оба xibs почти идентичны, за исключением размеров и позиций просмотров.

Чтобы сузить проблему, я использовал Instrument TimeProfiler, чтобы узнать, что вызывает проблему. Как оказалось, TimeProfiler показал несколько вызовов [NSISEngine optimize] (срабатывает NSLayoutConstraint). В портретном режиме было больше звонков, и эти звонки заняли гораздо больше времени. Далее по дереву я увидел, что в портретном режиме [NSISEngine optimize], называемом [NSISEngine fixupIntegralizationViolations], а в ландшафте это не так.

Я даже удалил все viewcontroller из приложения, за исключением rootVC, и еще один, который представлен rootVC. Представленный vc содержит только некоторые изображения, кнопки и некоторые анимации. Он имеет только один xib для обеих ориентаций и (как и все остальные), выложенные с автозапуском.

Макет работает так, как и в обеих ориентациях, и нет двусмысленностей (насколько я могу судить. по крайней мере po [[UIWindow keyWindow] _autolayoutTrace] не показывает).

Я прикрепил скриншот TimeProfile процесса презентации vc. Один для портрета и один для пейзажа. Как вы можете видеть, в ландшафте вызовы на [NSISEngine optimize] занимают всего миллисекунду, а в портрете - более 3000 мс.

Есть ли кто-нибудь, кто может сказать мне, почему это так? Или, может быть, есть идеи, что я могу сделать, чтобы выяснить, в чем проблема?

Любая помощь будет принята с благодарностью!

спасибо

Ссылка на увеличенную версию изображения: ссылка

Instruments Timeprofiler screenshot

4b9b3361

Ответ 1

Я подал техническую поддержку по этой проблеме и, наконец, получил ответ, что это скорее всего ошибка. Отчет об ошибке подан. Надеюсь, они скоро это исправит. Если есть новости, я обновлю этот ответ.

Ответ 2

Я столкнулся с одной и той же проблемой с умеренно сложным представлением, где она отлично работала на не-Retina iPads или Retina iPad в портретном режиме. В ландшафтном режиме на устройстве Retina потребовалось 10 раз дольше, чтобы отобразить popover или нажать другой вид в стеке представлений. Я закончил замену XIB файла ручным кодированием loadView в контроллере представления. Это, похоже, устранило проблему. Конструктор интерфейсов имеет тенденцию создавать чрезмерные ограничения, поэтому получение этого под контролем является ключом к хорошей производительности макета.

Я также открыл билет поддержки по этой проблеме.

Update:

Я нашел причину в своей ситуации. Это был следующий набор ограничений:

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-ю ширину родительского представления. Это теперь хорошо работает, процесс загрузки popover теперь занимает менее 300 мс, а не 2000 мс.

Ответ 3

У меня была такая же проблема вчера на устройстве Ipad iOS6.1. Прибор приложения обнаружил, что метод fixupIntegralizationViolations принимал около 300 мс каждый раз (20 раз, что очень много), что делает приложение абсолютно бесполезным.

Моя проблема была очень похожа на комментарии Джека Кокса, но я решил это по-другому. Мое ограничение:

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

Проблема заключается в том, что parentView здесь является полной шириной ландшафта iPad, поэтому математика этого ограничения давала каждой кнопке эту ширину: (1024-50)/3 = 324.6666667.

Как правило, это не проблема в автозапуске, так как он заботится о больших числах с плавающей запятой и правильно их округляет, но, похоже, в окружении iPad iOS6 Landscape это число вызывает ошибку, которая блокирует пользовательский интерфейс. Чтобы обойти это все, что мне нужно было сделать, это изменить sortButton, чтобы иметь 52, поэтому каждая ширина кнопок теперь равна: (1024-52)/3 = 324. Это все. Теперь метод fixupIntegralizationViolations занимает около 1 мс каждый раз.

Интересно, что использование 52 дает ему десятичную ширину в Пейзаже, но оно дает десятичное число в портрете: (768-52)/3 = 238.666667. Однако у портрета нет ошибок, и автозапуск округляет числа правильно.