4 August 2014

Ниндзюцу Xcode

Development for iOS
Если ты много времени проводишь в одном и том же окружении — рано или поздно возникает желание начать как-то экономить свое время и оптимизировать свои действия. В этой статье речь пойдет о некоторых рабочих инструментах и подходах, которые накопились у меня за время программирования под iOS в IDE XCode от очевидных и часто применимых, до редких и довольно тяжеловесных.


1.Command+Shift+O


Пожалуй, начну с моего любимого шотката в XCode. Его возможности достаточно широки для того, чтобы можно было его считать вполне себе самостоятельной фичей. После его нажатия перед вами откроется вот такое вот окно:

На мой взгляд это самый быстрый способ навигации по приложению, потому-что
  • Как видно из скриншота — не требует того, чтобы вы помнили точное название. Ему достаточно, если вы укажите несколько букв из названия в порядке, в котором они идут.Например слово из середины. Или первые две буквы элементов именования
  • Помимо навигации по файлам так же дает навигацию по классам, методам, свойствам класса, структурам.


2.Сниппеты


Об этом уже писали на хабре вот тут, например, но если уж собирать воедино, то и это нельзя обойти.
Сниппеты — это куски реиспользуемого кода, который можно вставлять в проект, лишь набрав ключ этого куска.
В принципе, там написано достаточно, поэтому хотелось бы добавить лишь два момента: ссылку на симпатичную подборку сниппетов и ответ со stackOverflow, который отвечает нам — как перенести свою библиотеку сниппетов с одного компьютера на другой.

Alcatraz


3.Проект Alcatraz

Менеджер плагинов для икскода. Встраивается в сам икскод, доступен в меню Window->Package manager

Плагинов есть целая прорва — от цветовых тем, до довольно значительных проектов, предлагающих live coding, почти как на свифте (правда устанавливать их можно на свой страх и риск, большинство из них не очень хорошо поддерживается, а значит несет определенные риски).
Очень удобная установка и отключение в 1 клик. В каждом плагине есть ссылка на его сайт или гитхаб, для многих из этого же менеджера доступны картинки или gif-превью.
Я с помощью менеджера пользуюсь некоторым количеством инструментов, в частности:

4.Derived data Exterminator



Из названия понятно, что этот инструмент предлагает быстро почистить папку с данными, оставшимся от предыдущих компиляций — иногда она занимает много места, особенно если работаешь с несколькими проектами одновременно.

5.FuzzyAutocomplete


Значительно расширяет autocomplete — он начинает работать примерно, как сочетание Cmd+Shift+O — то есть теперь не обязательно помнить первые буквы каждого метода или класса.
Люди его воспринимают достаточно по разному — теперь нечасто автокомплит уменьшается до одного варианта и создается впечатление большой кучи информационного мусора, но я без него теперь чувствую себя гораздо хуже.

6.Полезная мелочевка

Несколько маленьких, но приятных приспособлений для автокомлпита, таких как
-QuickLocalization (переводит @«content» в NSLocalizedString(@«content»,@«content»))
-OMColorSense (в автокомплите показывает цвет, когда заполняешь поля инициализации UIColor)
-XToDo (дает окошко, в котором можно просматривать в TODO, FIXME и прочие тэги по всему проекту)
-KSImageNamed (в автокомплите добавляет файлы графических ассетов и отображает их — делая imageNamed: куда более удобным для использования)

На этом закончим с Alcatraz — каждый имеет возможность выбрать из списка что-то себе по вкусу.

Interface builder


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

7.User defined runtime attributes


Это инструмент для KVC, доступный в IB — позволяет на этапе вызова метода InitWithCoder при инстанцировании объекта задавать значение некоторых свойств. По сути, его действие аналогично вызову метода [self setValue:@«value» forKey:@«key»] при инициализации объекта. Таким образом это позволяет вынести в IB файл достаточно широкий спектр настроек приложения, которыми может заниматься в том числе не-программист.

8.Инстанцирование объектов



IB позволяет управлять созданием не только объектов-наследников от элементов UIKit, но и любых произвольных объектов. (С помощью предыдущего пункта как раз можно управлять еще и каким-то свойствами создаваемых объектов) У них, как и у наследников UIKit, будет вызван конструктор initWithCoder: и они точно так же будут уничтожены при выходе контроллера из зоны видимости и стэйка Navigation Controllera, если разработчиком не предусмотрено обратного.
Я, например, пользуюсь этим инструментом для того, чтобы быстро изменить свойство многих UI элементов, когда UIAppearance и наследование по тем или иным причинам не подходит. Например, когда заказчик пожелал добавить на каждую кнопку в проекте градиент, а на некоторые еще и тени это решилось созданием двух декорирующих классов и развешиванием их в IB.

9.IBDesignable(XCode 6)


Подробно можно прочитать вот тут.

По сути — является удобной оболочкой над User defined runtime attributes — позволяя делать некоторые свойства классов доступными для изменения посредством IB. Это, конечно, еще не дает возможность писать полноценные кастомные UI-компоненты, но неплохо к этому приближает.

Структура проекта


10. .pch-файл(XCode 5-, в XCode 6 добавляется вручную)

В каждом проекте обязательно есть .pch файл (как правило в папке Supporting Files), который представляет собой заголовочный файл, подключаемый к каждому заголовочнику.
То есть фактически неплохое место для подключения общеиспользуемых на проекте макросов и хидеров (таких как хидеры CoreData или, например Cocos2d для игровых проектов)

Мультиязычность

Вообще, XCode это среда не только для Objective-C. И даже не только для Swift. Это большая и взрослая IDE, с помощью которой можно разрабатывать и на других языках

11.1.Интегрированные языки

Для меня было приятным откровением, что XCode имеет поддержку языков YACC и LEX из коробки. В проект достаточно добавить .y и .l (или .ym, .lm или .ymm, .lmm в зависимости от тех особенностей, которые вы хотите уметь при компиляции — первые два, например не смогут скомпилироваться с Objective-C кодом, а в последних можно использовать C++-stl)
У них есть своя секция настроек в проектном файле

Обратите внимания — что так как эти языки поддерживаются из коробки, то из коробки же генерятся и строки для компиляции, что в какой-то момент послужило неприятным сюрпризом — например XCode долго игнорировал мою попытку развести два генерируемых YACC файла по разным неймспейсом, потому что соответствующая директива перебивалась автоматически заполняемой XCodeом (опция Generated file stem, если кому интересно)


11.2.Неинтегрированные языки

Не стоит забывать и о том, что для некоторых задач Objective-C не самый подходящий язык. А расставаться с XCode все так же не хотелось, поэтому вот тут можно найти описание, как прикрутить к XCode, например Perl.
Если кто-то ищет вдохновения о применении: на перле можно организовать скрипт, который на примере JSON реквеста и респонса генерирует код .h и .m иерархии дата-объектов, под который укладывается эти данные.

Для многих языков XCode имеет встроенную подсветку.

Внешние инструменты


12. Автоматор

Одна из потрясающих особенностей macOS как системы — так это приятная и достаточно удобная среда для автоматизации всего, чего душе угодно.
Получить первое представление об этом можно вот тут
Туториал по практическим применениям — очень рекомендую.
Если же эта тема действительно увлечет — есть замечательная наводка на то, что можно создавать собственные подпрограммы для автоматора.

Я недавно начал использовать его, но вижу довольно много интересных применений: От простейших многострочных комментариев, до поиска выделенной строчки кода в коммитах гита — и на что хватит фантазии.

К слову, в Настройках системы (программа Keyboard) можно назначить на созданные сервисы шорткаты и сделать жизнь еще легче.

13.Synx


Этот инструмент позволяет привести проект в файловой системе к виду, в котором он присутствует в проекте. Запускается через командную строку. Надежен — операций, в которых он не уверен — он просто не делает, о чем заранее предупреждает.

А с утра пришли в голову еще пара вещей, о которых я забыл. Хотя они тоже почти очевидны, но тем не менее это отвечает на один из самых частых вопросов в ObjC группах:

Отладка


14. Брейкпоинты.

Отлаживать приложение приходится всем. И иногда подолгу. И пользоваться этими вещами я начал далеко не сразу. А зря!
Один из ключевых советов — всегда держать тот или иной Exception Breakpoint включенным. Exception breakpoint срабатывает, когда какое-то исключение срабатывает. В случае, если это исключение необработанное при выключенным брейкпоинте не будет показан стэк, приведший к ошибке. Наверняка все так или иначе сталкивались с проблемой поиска ошибок навроде [array addObject:nil] или out of range. Так вот, такие брейкпоинты — это способ ловить такие проблемы ровно в месте их возникновения.

Вторая вещь о брейкпоинтах, которую хотелось бы отметить — это возможность выставлять условные брейкпоинты.

Если у вас есть есть кусочек крайне сильно используемого в проекте кода (например, CCNode в cocos2d), то без условий отловить конкретную проблему бывает весьма и весьма проблематично. Они поддерживают обычный objective-C синтаксис, то есть там можно проверить, что передаваемый объект конкретного класса, что имеет конкретное значение какого-то свойства и так далее. Очень удобно!
Ну и да, работа условных брейкпоинтов очень сильно замедляет работу приложения — так что лучше с ними не перебарщивать.

15. Поколения

И хотелось бы добавить о поиске утечек памяти в коде. Как правило для этого используется Instruments с пресетом Leaks, но основная проблема этого инструмента в том, что бывают такие утечки, которые этим инструментом за утечки не считаются и мне приходилось встречаться с кодом, где за юзкейс утекает несколько мегабайт, а Leaks не показывает ровным счетом ничего — это связано ровно с тем, что, собственно, считается утечкой. Так что последнее время для поиска существенных проблем с памятью я использую инструмент Allocations.
Важно. Этот инструмент есть отдельно, но запускать его лучше все-таки в пресете с Leaks — потому что будучи запущенный отдельно он не всегда корректно способен расписать историю Retain/Release для конкретного объекта — не знаю, баг это или фича.
Так вот. Нажатие кнопки mark generation по сути маркирует каждый созданный к этому моменту не-маркированный объект (в широком смысле — память выделенная под структуры тоже маркируется). Дальше, по мере жизни приложения, в поколении остаются только те объекты, которые к текущему моменту не освобождены.
Развернув конкретное поколение достаточно несложно найти классы, используемые именно в вашем проекте, а так же посмотреть, почему они до сих пор живы (для каждого объекта можно посмотреть историю — где и когда он получал сообщение retain и где release).

Прочитать о конкретных аспектах применения этого инструмента рекомендую вот здесь.

Спасибо за чтение!
и буду очень признателен каким-то вашим трюкам и наработкам.
Tags:xcodeскорость работыинструменты разработчикаудобство работыios разработка
Hubs: Development for iOS
+33
23.2k 215
Comments 19