В среде Xcode есть инструменты для графического и числового описания внутреннего поведения приложения, за которыми необходимо следить.

В навигаторе отладки среды Xcode 5 впервые появились индикаторы (gauges), позволяющие отслеживать загрузку центрального процессора и степень использования памяти в любой момент работы приложения. Кроме того, сложное и мощное служебное приложение Instruments собирает профильные данные и помогает отслеживать проблемы, связанные с управлением памятью, а также собирает числовую информацию, необходимую для улучшения производительности приложения и его динамичности. Возможно, на этапе завершения своего приложения вы захотите использовать приложение Instruments для повышения его эффективности (преждевременная оптимизация — это лишь пустая трата времени и сил).

Индикаторы в навигаторе отладки работают во время сборки и выполнения вашего приложения. За ними необходимо следить, чтобы знать степень загрузки центрального процессора и использования памяти. Щелкните на индикаторе, чтобы увидеть подробную информацию в окне редактора. Индикатор не предоставляет полной информации, но чрезвычайно динамичен и всегда активен, поэтому с его помощью в любой момент можно легко понять, что происходит с вашим приложением. В частности, если возникла проблема, например, неожиданно длинный период высокой нагрузки центрального процессора или завышенное потребление памяти, ее можно выявить с помощью индикатора и отследить, используя утилиту Instruments.

На рис. 9.11 я продемонстрировал несколько моментов работы моего приложения, повторно выполняя наиболее типичные действия, ожидаемые от пользователя. Столбцы индикатора Memory в навигаторе отладки выглядят совершенно одинаковыми, что является хорошим признаком, но просто для подстраховки я щелкнул на нем, чтобы открыть более крупную диаграмму использования памяти в окне редактора. Некоторые действия, выполняемые впервые, вызывают всплески и падения нагрузки на память, но при повторении нагрузка на память выравнивается, поэтому нет никаких признаков проблемы.

 Индикаторы навигатора отладки

Pиc. 9.11. Индикаторы навигатора отладки

 

Утилиту Instruments можно использовать как в симуляторе, так и на устройстве. Именно на устройстве будет выполняться окончательное тестирование, причем некоторые инструменты (такие как Core Animation) доступны только на устройстве.

Для того чтобы начать работу с утилитой Instruments, укажите целевое устройство в раскрывающемся списке Scheme на инструментальной панели в окне проекта и выберите команду Productoprofile. Допустим, что в схеме вашего приложения указано действие Profile; по умолчанию это значит, что ваше приложение будет использовать конфигурацию настроек Release. Если приложение выполняется на устройстве, вы можете увидеть некоторые сообщения о проверке, но их можно спокойно игнорировать. Утилита Instruments начинает работу; если в раскрывающемся списке Instrument для действия Profile установлено свойство Ask on Launch (по умолчанию), утилита Instruments откроет диалоговое окно, в котором можно выбрать шаблон слежения.

В качестве альтернативы можно щелкнуть на кнопке Profile In Instruments в редакторе индикатора в навигаторе отладки; в этом случае будет запущена утилита Instruments и автоматически выбран соответствующий шаблон слежения. Диалоговое окно предлагает две возможности: команда Restart останавливает выполнение вашего приложения и запускает его заново с помощью утилиты Instruments, а команда Transfer не препятствует выполнению приложения, подключая к нему утилиту Instruments. Обычно программисты пользуются командой Restart: это значит, что вы заметили проблему на индикаторах и хотите воспроизвести ее более подробно под наблюдением утилиты Instruments.

Когда утилита Instruments работает, вы должны взаимодействовать с приложением как пользователь; утилита Instruments будет записывать статистические показатели. После запуска утилиты Instruments можно уточнить профиль данных, которые вас особенно интересуют, и сохранить окно Instruments как пользовательский шаблон.

Использование утилиты Instruments требует знаний, которые выходят за рамки рассмотрения данной книги. Этой утилите можно (и нужно) посвятить отдельную книгу. За подробной информацией обращайтесь к документации компании Apple, особенно к справочнику Instruments User Reference and Instruments User Guide. Кроме того, этой утилите посвящено много видеозаписей конференции WWDC; обратите внимание на сессии, в именах которых используется слово “Instruments” или “Performance”. Здесь я просто демонстрирую работу этой утилиты без пространных объяснений.

Начнем с построения диаграммы для степени использования памяти при выполнении приложения TidBITS News при его запуске и во время работы пользователя. Память мобильного устройства — это очень скудный ресурс, поэтому важно не слишком сильно ее захватывать. Я установил в качестве цели симулятор и выбрал команду Products Profile. После запуска утилиты Instruments я выбрал шаблон слежения Allocations и щелкнул на кнопке Profile. В симуляторе началось выполнение моего приложения, я какое-то время с ним поработал, а затем остановил утилиту Instruments, которая тем временем построила диаграмму загрузки памяти (рис. 9.12). Изучая эту диаграмму, я обнаружил несколько пиков: первый — при загрузке приложения, второй — в момент, когда приложение загружало и анализировало RSS-канал; но максимум достиг всего лишь 5,40 Мбайт, после чего приложение практически все время использовало примерно 2 Мбайт. Эти числа свидетельствуют об очень умеренном потреблении памяти, а также о том, что после запуска приложение работает стабильно, чему я очень рад.

 Диаграмма загрузки памяти во времени, построенная утилитой Instruments

Рис, 9.12. Диаграмма загрузки памяти во времени, построенная утилитой Instruments

 

Другое направление анализа с помощью утилиты Instruments — выявление утечки памяти. Как сказано в главе 12, утечка памяти возможна даже при использовании механизма ARC. В тривиальном примере, рассмотренном ниже, используются два класса: MyClassl и MyClass2; класс MyClassl имеет переменную экземпляра, которая относится к классу MyClass2, а класс MyClass2 имеет переменную экземпляра, которая относится к классу MyClassl. Рассмотрим следующий код:

MyClassl* ml = [MyClassl new];

MyClass2* m2 = [MyClass2 new];

m1=.ivar = m2;

m2.ivar = ml;

Как указано в главе 12, можно предпринять некоторые меры, препятствующие утечке памяти; но я пока не делал этого, чтобы утечка памяти все же произошла. Установим целью приложения симулятор и выберем команду Product^Profile; происходит запуск приложения Instruments. Затем выберем шаблон слежения Leaks и щелкнем на кнопке Profile. Приложение начинает выполняться в симуляторе, и через 10 секунд (именно такой интервал установлен по умолчанию для анализа утечек к утилите Instruments) обнаруживается утечка памяти. Щелкнув на нескольких кнопках, можно вывести на экран диаграмму ошибки, вызывающую утечку памяти (рис. 9.13)!

 

 Описание утечки памяти утилитой Instruments

Puc. 9.13. Описание утечки памяти утилитой Instruments

 

Если анализ использования памяти осуществляется с помощью утилиты Instruments, то, возможно, целесообразно изменить схему, чтобы действие Profile использовало конфигурацию настроек Debug. По умолчанию она использует конфигурацию Release, которая оптимизирует ваш код и запутывает анализ использования памяти.

 

В последнем примере я пытался выяснить, почему в моем приложении Albumen переключение с главного представления на детализированное происходит слишком медленно. В качестве цели я установил устройство, потому что именно на нем необходимо измерять скорость выполнения программы, и выбрал команду Products Profile. Произошел запуск утилиты Instruments, в качестве шаблона слежения я выбрал Time Profiler и щелкнул на кнопке Profile. На экране появилось главное представление; я коснулся ячейки в табличном представлении, и после значительной задержки на экране появилось детализированное представление. В этот момент я остановил работу утилиты Instruments и посмотрел на ее сообщение.

Как показано на рис. 9.14, этот переход занял примерно три секунды. Если щелкнуть на треугольниках открытия в нижней части окна, окажется, что большая часть этого времени уходит на выполнение метода СА: : Layer: : layout_and_display_if_needed. Это не мой код; он скрыт глубоко в недрах каркаса Cocoa. Однако, щелкнув на маленькой стрелке, которая появляется справа от строки, на которую указывает курсор мыши, можно увидеть стек вызовов и выяснить, каким образом мой код связан с этим методом (рис. 9.15).

 

 Временной профиль в утилите Iпstrитeпts

Рис. 9.14. Временной профиль в утилите Iпstrитeпts

 

Разбор временного профиля 

Puc. 9.15. Разбор временного профиля

 

С этим методом связана одна строка моего кода: taЬleView:heightForRowAtindexP а th:. Этот метод выравнивает высоту ячеек табличного представления, чтобы их было видно на детализированном представлении. Дважды щелкнув на этой строке в листинге, можно увидеть временной профиль моего кода (рис. 9.16).

 

Временной профиль кода

Рис. 9.16. Временной профиль кода

 

 

Это действительно полезная и угнетающая информация. Огромная часть времени тратится на выполнение метода каркаса Сосоа systemLayoutSizeFi ttingSize: . Этот метод вычисляет высоту ячейки табличного представления, используя механизм Autolayout. Он работает прекрасно, но затрачивает относительно много ресурсов, поэтому следует хорошо подумать, стоит ли его использовать.


 

 

 

Добавить комментарий