Отладка с Xcode 4.5 для разработчиков среднего уровня

от автора

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

К счастью, Xcode дает нам множество инструментов, чтобы держать в страхе этих жуков. Это, конечно отладчик, который мы знаем и любим, но есть многое, что он ещё может сделать для вас, чем простое исследование шаг за шагом переменных и кода!

Это руководство для iOS-разработчиков среднего уровня квалификации, тут вы получите практический опыт работы с некоторыми не очень известными, но чрезвычайно полезными методами отладки, такими как:

  • Отказ от использования NSLog и использование вывода сообщений в отладочную консоль точками останова;
  • Отказ от комментирования кода и использование предупреждений от компилятора;
  • Использование условных точек останова;
  • Динамическое изменение данных с помощью LLDB;
  • И многое другое!


Видите ли, для меня цель — быть ленивым разработчиком. Я предпочитаю делать тяжелую работу в начале, так что бы потом расслабиться в конце. К счастью, LLDB (интегрированный в Xcode отладчик) ценит мое время. У него есть отличные инструменты, поэтому я не приклеен к моему компьютеру весь день и ночь.

Давайте взглянем на эти инструменты. Откиньтесь поудобнее в кресле. Откупорьте ваш любимый напиток. Настало время быть ленивым!

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

Приступаем

Приложение, которое мы используем в этом руководстве, можно скачать здесь.

Приложение называется Gift Lister. С его помощью вы отслеживаете подарки, которые вы хотите подарить людям. Приложение похоже на Gifts 2 HD, которое недавно было удостоено приза сайта, как Наиболее Визуально Впечатляющее Приложение. Gift Lister вроде Gifts 2 HD, но гораздо, гораздо хуже.

Gift Lister завален ошибками. Разработчик (это я, но в другой рубашке) был через-чур честолюбивым и попытался избавить приложение от ошибок по старинке. Да, приложение по-прежнему не работает.

Это руководство проведет вас шаг за шагом к исправленному приложению, и в то же время вы будете настолько ленивыми, насколько это возможно. Хорошо, давайте начнем, но не спешите сильно.

Откройте проект и посмотрите на него. Вы заметите, что приложение представляет собой простую оболочку для данных Core Data.

Примечание: Если вы не знаете, что такое Core Data, не волнуйтесь! Core Data – это фреймворк по работе со структурированными данными, о котором у нас есть отдельное руководство. В этом уроке вы не будете ни подробно разбираться с фрейворком, ни работать с объектами Core Data, так что вам не нужно много знать об этом. Просто имейте в виду, что Core Data загружает объекты и сохраняет их, и вам не надо этим заниматься.

Настройка консоли отладчика

Первое, что нужно сделать, когда вы начинаете сеанс отладки — это открыть консоль отладки. Вы можете открыть её, нажав на эту кнопку на главной панели инструментов:

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

Откройте свойства Xcode, выбрав пункт меню Xcode\Preferences (⌘,). Нажмите на кнопку Behaviors (кнопка с шестерёнкой).

Слева, в разделе Running, нажмите пункт Starts. В правой стороне окна нажмите седьмою галочку, а затем выберите пункт Variables & Console из ставшего доступным выпадающего списка.

Сделайте то же самое для пунктов Pauses и Generates Output, находящихся в этом же разделе Running, ниже пункта Starts.

Выбранное в выпадающем списке значение Variables & Console говорит отладчику, что нужно показывать список локальных переменных, а также показывать отладочную консоль каждый раз, когда начинается сессия отладки. Если вы хотите видеть только отладочную консоль, вы должны выбрать значение Console View. Точно так же, если вы хотите видеть только список переменных, вы должны выбрать Variable View.

Вариант по умолчанию Current Views обеспечивает отображение в том виде, каким оно было во время последней сессии отладчика. Например, если вы закрыли окно с переменными и смотрели только на консоль, то только консоль откроется в следующий раз, когда начнётся отладка.

Закройте диалоговое окно с настройками, откомпилируйте и запустите приложение.

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

Вот так сразу, вы не сможете увидеть источник ошибки. Чтобы найти его, вам нужно добавить точку останова на исключение.

Включите навигатор точек останова, как показано ниже:

Затем нажмите на знак плюс в нижней части панели. В появившемся меню выберите пункт Add Exception Breakpoint.

Появиться вот такое окно:

Поле Exception дает вам выбор типа инструкций для которых обрабатывать исключения (Objective-C, C++, или Все). Оставьте стандартный вариант All.

Поле Break позволяет выбрать момент, когда останавливать программу, когда ошибка появилась (On Catch) или когда произошло уже исключение (On Throw). Оставьте значение по-умолчанию — On Throw. Если вы в своём проекте делаете обработку исключений, то выбирайте вариант On Catch. Для целей нашего руководства подойдёт On Throw.

Два последних поля мы обсудим в этом руководстве позже. Нажмите кнопку Done, а затем запустите приложение.
На этот раз результат намного яснее.

Взгляните на консоль отладчика. Она наполнена отладочными сообщениями. Многие из них не нужны.

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

Откройте AppDelegate.m, и вы увидите кучу старых сообщений NSLog в процедуре didFinishLaunchingWithOptions. Удалите их.

Давайте найдем остальные сообщения NSLog. Запустите поиск строки «NSLog (@«в viewDidLoad»);».

Нажмите на результат поиска и перейдите в FriendSelectionViewController.m.

Вот момент, когда усилия, которые вы тратите на обработку журнала отладки, начинают накапливаться. Затрат, вроде, не так много, но минуту копятся. И к концу проектного цикла эти неприкаянные минуты легко складываются в часы.

Ещё один недостаток прямого использования в коде команд вывода информации в отладочный журнал то, что каждый раз, когда вы что-то добавляете в код, вы увеличиваете риск добавления новых ошибок в код. Несколько нажатий клавиш, немного автозаполнения, небольшое отвлечение внимания — и в вашем рабочем приложении уже есть ошибка.

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

Во-первых, закомментируйте обе команды NSLog. Затем добавьте точку останова, щелкнув левой клавишей мыши по полю слева от каждой команды NSLog.

Ваш код должен выглядеть следующим образом:

Щелкните правой кнопкой мыши первую точку останова и выберите в появившемся меню пункт Edit Breakpoint. В диалоговом окне выберите Log Message из выпадающего списка. В первом текстовом поле введите «in viewDidLoad». Диалоговое окно должно выглядеть так:

Нажмите кнопку Done, а затем запустите приложение. Теперь вы должны увидеть строку «in viewDidLoad» в консоли — но теперь это делает точка останова, а не команда NSLog!

Примечание: На протяжении этого руководства я буду заставлять запускать приложение после каждого изменения точек останова, потому что так проще объяснять. Но помните главное: точки останова можно изменять во время работы приложения.

Но есть одна большая проблема. Точка останова выдаёт сообщение и останавливает программу, а вам остановка в этом месте не нужна. Изменить такое поведение очень просто.

Правой клавишей мыши нажмите на точку останова и выберите пункт меню Edit Breakpoint. В нижней части диалогового окна, поставьте флаг «Automatically continue after evaluating». Теперь запустите приложение снова.
На этот раз точка останова выводит сообщение, но программа останавливается на второй точке останова.

Исправляем вторую точку останова. Выбираем пункт Log Message, в текстовом поле пишем «Loading friends…». В нижней части диалогового окна ставим флаг «Automatically continue after evaluating». Нажимаем кнопку Done. Теперь запустим снова.

Приложение прекрасно работает до того момента пока не выдаёт исключение.
Верьте или нет, но вы всё ещё делаете слишком много работы. Войдите в правку первой точки останова и замените текст «in viewDidLoad» на текст «%B». Теперь запустите приложение снова. Консоль должна выглядеть следующим образом:

Сокращение %B выводит имя метода. Вы также можете использовать сокращение %H, и в журнале отладки будет выведена информация о том, сколько раз вы попали на эту точку останова.

Перед тем как исправить ошибку в программе, давайте немного повеселимся. Войдите в правку первой точки останова. В диалоговом окне нажмите на кнопку с плюсом. Эта кнопка позволяет добавить ещё несколько действий для точки останова.

Выберите «Log Message» у нового действия и напишите текст «To be, or not to be». Ниже этого текста выберите переключатель «Speak Message». Диалоговое окно должно выглядеть следующим образом:

Запустите приложение.

Примечание: Как это ни странно, но эта функция действительно может быть полезной! Звуковые сообщения могут быть использованы, например, при отладке сложного сетевого кода.
К сожалению, кроме вывода строки простого сообщения, действие Log Messages не имеет гибкости NSLog. Но это тоже решаемо.

Чтобы это продемонстрировать, давайте исправим ошибку в программе. Запустите программу и дайте ей аварийно завершиться. Трассировочный стек гласит:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+entityForName: nil is not a legal NSManagedObjectContext parameter searching for entity name 'Friend' 

Что-то не работает в Core Data.
Просмотрев код, вы увидите, что NSManagedObjectContext получен из объекта DataStore. Наверно, DataStore и есть причина этой проблемы. DataStore не часть Core Data. Это специальный объект используется для инкапсуляции некоторых из центральных объектов Core Data.

Добавьте точку останова после этой строки:

DataStore *DataStore = [DataStore sharedDataStore]; 

Войдите в режим редактирования новой точки останова, в поле Action выберите Debugger Command из выпадающего меню. В текстовом поле напишите текст:

po dataStore 

Поставьте флаг «Automatically continue after evaluating» и запустите программу.

Как вы и подозревали, dataStore равен nil.

Примечание: po – команда отладчика, которая выводит содержимое объекта (print object). Если вам нужно получить содержимое обычной переменной, используйте команду р. Чтобы узнать больше о командах отладчика, читайте документацию LLDB.

Откройте DataStore.m, и вы увидите в методе sharedInstance, что процедура возвращает пустое значение. Измените строку

return nil 

на строку

return sharedInstance 

Запустите приложение, ура!, приложение работает!

Точки останова и выражения

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

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

Давайте восстановим информации в консоли их былую славу. Войдите в режим редактирования последней точки останова в FriendSelectionViewController.m. В поле с текстом выводимой команды напишите следующее:

expr (void)NSLog(@"dataStore: %@", dataStore) 

Команда expr выдаёт в реальном времени значение выражения. Команде нужно знать тип возвращаемого выражением значения. Так как никакого значения процедура NSLog не возвращает, укажем (void). Запускаем приложение. В отладочной консоли будет подобное этому:

2012-12-20 08:57:39.942 GiftLister[1984:11603] dataStore: <DataStore: 0x74c3170> 

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

Существует одна небольшая разница между вызовом NSLog в точке останова по сравнению с вызовом этой процедуры в коде программы. Под результатом NSLog из точки останова выводится текст "". Этот текст получен от LLDB и, к сожалению, вы не можете подавить его. Хорошая новость в том, что это сообщение будет убрано в следующей версии Xcode.

Теперь давайте отключим выдачу сообщений в консоль отладки. Нужно только нажать кнопку с изображением точки останова.

Нажмите на нее, а затем запустите приложение. Консоль отладки чиста.
Вы также можете отключить какую-то конкретную точку останова, нажав на синий маркер рядом с конкретной точкой в навигаторе точек останова.

Дни, когда вы заполняли ваш код командами отладки, прошли!

Комментарии, предупреждения и ошибки

Приложение работает. Теперь нужно создать в нём друзей, для которых вы сможете хранить список рекомендаций по выбору для них подарка.

Запустите приложение, нажмите ячейку таблицы «Add a friend». Приложение покажет окно с текстовым полем для имени и полем для даты. Введите имя друга и его день рождения. Нажмите кнопку ОК.

Вы вернетесь к корневому окну и увидите вашего нового друга, добавленного в таблицу. Нажмите кнопку «Add a friend» ещё раз.

Введите имя ещё одного друга, только на этот выберите день рождения 31 февраля 2010.

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

Откройте AddFriendViewController.m и добавьте точки останова в начале метода -(void)saveFriend.

Примечание: Поиск методов в больших файлов может занять много времени. Можно, конечно, вручную рассматривать каждую строку, пока вы не наткнётесь на нужный метод. Хороший способ заключается в использовании меню со списком методов. Я предпочитают делать поиск, но не в поисковом навигаторе, а в меню со списком методов. Чтобы сделать это, нажмите на меню со списком методов, а потом начните печатать искомое имя метода. Имя метода отобразиться, как в обычном поле поиска.

В симуляторе нажмите кнопку «Add a friend» и как и раньше, добавьте неверную дату. Пошагово пройдите в отладчике по методу, пока не дойдете до этой строки:

if ([self isValidDateComposedOfMonth:month day:day andYear:year]) { 

Зайдите в метод. Всё ясно. Тут никто ничего не проверяет. Тут только комментарий с обещаниями сделать это позже.

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

Лучший способ их не потерять — это выделить их.

В первой строке метода -(void)isValidDateComposedOfMonth напишите следующую строку кода:

#warning Add validation code 

В проекте сразу же появиться новое предупреждение. Переключитесь в Issue Navigator (⌘4), и вы увидите предупреждение в списке, вместе с остальными сообщениями.

Если вы из того типа разработчиков, что игнорируют предупреждения, попробуйте тогда такой вариант:

#error Fix your code 

В проекте сразу же появиться новая ошибка. Вы не сможете скомпилировать код, пока эта строка не будет удалена. Это один из способов отслеживать свой же комментарии.

Удалите внесённые строки, чтобы приложение могло компилироваться.
Вы также можете оставить сообщение в меню методов. В первой строке метода -(void)isValidDateComposedOfMonth напишите следующую строку кода:

// TODO: Add validation code 

Сохраните файл, а затем откройте меню методов. Вы должны увидеть что-то вроде этого:

Можно также написать FIXME:, ???: и !!!:. Строка ???: означает: «У меня к вам вопрос», а !!!: значит «Это важно!».

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

Озвучка наших действий

К этому моменту вы должны были внести достаточно данных в приложение. И теперь пришло время всё это сохранить. С такими приложениями, как это, сохранять данные нужно часто, чтобы ничего не потерять. Но только не с этим приложением. Оно сохраняет данные только когда пользователь выходит из приложения.

Нажмите кнопку Back на панели навигации приложения, чтобы вернуться в корневое окно, и там нажмите кнопку Home. Вы можете сделать это из меню симулятора, выбрав пункт меню Hardware\Home или нажав круглую кнопку прямо на корпусе симулятора.

Теперь остановите программу в Xcode, потом опять запустите. Таблица с друзьями пуста. Приложение ничего не сохранило.

Откройте AppDelegate.m. В методе applicationDidEnterBackground, вы должны сразу увидеть проблему. Это метод doLotsOfWork. Работа этого метода занимает много времени, так что iOS принудительно прекращает выполнение приложения. В результате этого досрочного прекращении метод SaveData не вызывается.

Давайте сделаем так, чтобы данные сохранялись в первую очередь. В методе applicationDidEnterBackground переместите строку [[DataStore sharedDataStore] SaveData]; выше вызова метода doLotsOfWork следующим образом:

[[DataStore sharedDataStore] saveData]; [self doLotsOfWork]; 

Теперь добавьте точку останова на строке вызова doLotsOfWork. Войдите в окно редактирования этой точки. В поле Action поставьте значение Sound и рядом выберите звук «Submarine». Старайтесь избегать системных звуков, так как их можно не заметить.

Далее, установите флажок «Automatically continue after evaluating». Запустите приложение.

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

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

Чтобы сделать это, просто запишите ваши звуковые файлы в эту папку:
YOUR_HOME_DIRECTORY/Library/Sounds

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

Условия для успешной отладки

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

Выберите из списка ваших друзей одного, чтобы отрыть окно управления подарками. Это всего лишь сгруппированная таблица, которая может быть отсортирована по признаку, куплен уже подарок или ещё нет.
Нажмите на кнопку Add на панели навигации, чтобы добавить новый подарок. В качестве имени подарка напишите, например Обувь. Ценой, например 88,00. Нажмите кнопку ОК. Обувь должна появиться в списке подарков.

Теперь добавьте следующие подарки:

  • Санки / 540,00
  • Свечи / 1,99
  • XBox / 299,99
  • iPad / 499,99

Ой. Внезапно, вы поняли, что вы на самом деле хотели написать PS3 вместо XBox. Можно просто отредактировать запись, но ради обучения, отредактируем запись через отладчик.

Откройте GiftListsViewController.m и найдите метод cellForRowAtIndexPath. Добавьте точку останова на строке под эти условием:

if (gift) { 

Теперь щелкните правой кнопкой мыши на точке останова и выберите пункт меню «Edit Breakpoint».

Создадим условие для точки останова. Добавьте в поле Condition следующий код:

(BOOL) [gift.name isEqualToString:@"XBox"] 

LLDB требует от нас указать тип указанного выражения, поэтому поставим (BOOL) перед выражением. Нажмите кнопку Done.

Теперь, в программе нажмите на сегмент Bought. Таблица с подарками обновиться, но точка останова не срабатывает.

Нажмите на сегмент Saved. В этот раз отладчик остановит выполнение программы на нашей точке останова.

В консоли отладчика напишите следующее:

(lldb) expr (void) [gift setName:@"PS3"] 

Теперь нажмите кнопку продолжения работы программы, таблица продолжит загружаться. Вместо XBox в подарках будет написано PS3.

Так же можно было остановить программу в нужном месте, используя счётчик итераций. Удалите точку останова, которую мы использовали. Xcode может сбоить, когда редактируют условия точки останова. Лучше создать новую точку. Добавьте новую точку на том же месте. В этот раз заполните поле Ignore цифрой 3 (ведь наш подарок PS3– это элемент массива №3). Нажмите кнопку Done.

Теперь на сегмент Bought, а потом на сегмент Saved.

Мы должны выйти в режим отладки в правильном месте. Чтобы убедиться, что вы находитесь на правильном объекте, напишите:

(lldb) po gift 

Теперь вернём объект обратно в прежнее состояние:

(lldb) (void)[gift setName:@"XBox 360"] 

Таблица будет показывать исправленный подарок. Ну, разве редактирование в реальном времени — это не замечательно?

Запуск скриптов

При разработке приложений, управляемых данными, часто бывает нужно очищать хранилище данных. Есть несколько способов это сделать, начиная от сброса эмулятора iOS-устройства до поиска фактического хранилища данных на вашем компьютере и его удаления. Делать это каждый раз немного утомительно, поэтому будем ленивыми и заставим Xcode сделать это за нас.

Мы начнем с создания файла-сценария, или как его ещё называют — скрипта. Скрипт представляет собой список команд, которые автоматизируют некоторые действия операционной системы. Чтобы создать сценарий, создадим новый файл из меню приложения. Выберите пункт меню File\New\File (⌘N). В диалоговом окне, выберите iOS\Other и Shell Script в качестве типа нового файла.

В качестве имени файла напишите wipe-db.sh

Теперь вы должны найти фактическое хранилище данных. Откройте Terminal. Если вы не знаете, где находится Terminal, то вы сможете его найти в папке Application внутри папки Utilities (в русской версии OSX – Программы\Утилиты\Терминал).

После запуска терминала перейдите в свой домашний каталог, для этого в командной строке Терминала введите следующее:

YourComputer$ cd ~ 

Теперь получите список содержимого домашнего каталога с помощью команды:

YourComputer$ ls 

Если вы не видите в полученном списке папку с названием Library, введите следующую команду:

YourComputer$ chflags nohidden ~/Library/ 

Затем снова получите список содержимого домашнего каталога.

Теперь, перейдём в каталог, содержащий iPhone-симулятор, введя следующую команду:

YourComputer$ cd ~/Library/Application\ Support/iPhone\ Simulator/6.0/Applications 

Снова получите список файлов в папке:

YourComputer$ ls 

Вы увидите много различных каталогов, в зависимости от того, сколько приложений в настоящее время установлено в симуляторе. Вам нужно найти папку для GiftLister путём перебора. Для перехода в каждую папку, вам придется написать: cd длинное_цифро-букпвенное_название_папки.

Чтобы сэкономить время, напишите только первые три буквы названия папки, а затем нажмите TAB. Терминал сделает автозаполнение имени папки. Если не сделает, продолжайте пробовать вводить следующую букву, а потом нажимать TAB, пока не Терминал не сделает автозаполнение. В моем случае, у меня есть папка: 0B1E5AD3-7292-45A6-BB5D-F1C004AC47F9 поэтому я ввёл бы:

YourComputer$ cd 0B1 

А затем нажал бы на TAB.

После этого введите команду ls, чтобы увидеть содержимое каталога, и вы должны увидеть файл GiftLister.app. Если его там нет, попробуйте другую папку, вернувшись на предыдущий уровень командой “ls ..”.

Кроме того, этот проект сделан для iOS 6. Если вы используете другую версию симулятора, например, 5.1, то в пути к каталогу, установленных на симуляторе программ, вам нужно написать именно эту версию. То есть так:

YourComputer$ cd ~/Library/Application\ Support/iPhone\ Simulator/5.1/Applications 

Ну, вот вы нашли каталог нашего приложения. Напишите ещё команду:

YourComputer$ cd Library 

Затем посмотрите содержимое каталога:

YourComputer$ ls 

Вы увидите в каталоге файл giftlister.sqlite. Молодцы. Нашли.
Дайте команду, которая выведет полный путь каталога, в котором вы находитесь:

YourComputer$ pwd 

Скопируйте полученный путь в буфер обмена и вставьте его в Xcode в текст скрипта. В конец названия папки добавьте текст:

/giftlister.sqlite 

Примечание переводчика: Считаю, что в наш век, когда космические корабли бороздят здания Большого театра, описанный выше способ получения каталога, в котором хранится БД-файл приложения (giftlister.sqlite), непродуктивен.

Предлагаю более другой способ. Сразу после запуска Терминала введите эти команды:

YourComputer$ cd ~ YourComputer$ pwd YourComputer$ find . -name giftlister.sqlite 

Скопируйте результат поиска в буфер обмена и вставьте его в Xcode в текст скрипта. В строке результата уже будет имя файла, но только вместо точки в начале нужно написать строку типа «/Users/ИМЯ_ВАШЕГО_ПОЛЬЗОВАТЕЛЯ» (эту строку вы получите после выполнения второй команды – pwd).

В результате у вас в скрипте будет строка, подобной следующей:

/Users/Brian/Library/Application Support/iPhone Simulator/6.0/Applications/0B1E5AD3-7292-45A6-BB5D-F1C004AC47F9/Library/giftlister.sqlite 

К сожалению, некоторые папки содержат пробел:

/iPhone Simulator/ /Application Support/ 

Чтобы скрипт был обработан без ошибок, пробелы нужно обозначить спецсимволом, вот так:

/iPhone\ Simulator/ /Application\ Support/ 

Сделайте это в тексте скрипта и изменённый текст будет выглядеть подобно этому:

/Users/Brian/Library/Application\ Support/iPhone\ Simulator/6.0/Applications/0B1E5AD3-7292-45A6-BB5D-F1C004AC47F9/Library/giftlister.sqlite 

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

Сохраните скрипт и закройте его.

По умолчанию, скриптовый файл в ОС имеет права только на чтение. Вы должны дать ему права на исполнение. Откройте Терминал, вернитесь в свой домашний каталог, введя команду:

YourComputer$ cd ~ 

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

YourComputer$ cd Desktop YourComputer$ cd GiftLister 

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

YourComputer$ chmod a+x wipe-db.sh 

Команда chmod позволяет изменять права доступа к файлу. Параметр a+x разрешит исполнять наш скрипт всем пользователям и группам. Чтобы проконтролировать, дали вы права или нет файлу, выполните команду:

YourComputer$ ls -l 

Ничего себе…, как много сделали. Сделайте передышку. Вы это заслужили. Иногда лень может потребовать много работы.

Закройте Терминал и вернитесь в Xcode. Откройте AppDelegate.m. Установите точку останова на первой строке метода didFinishLaunchingWithOptions. Войдите в режим правки точки останова. В поле Action выберите «Shell Command». Нажмите кнопку обзора файлов и найдите скрипт, который мы с вами сделали. Поставьте флаг «Automatically continue after evaluating», нажмите Done.

Запустите программу. База данных будет удалена, в программе нет данных.

Симулятор имеет обыкновение кэшировать большие объемы данных, поэтому я предпочитаю запускать чистую сборку, нажав пункт меню Product\Clean (⇧⌘K) перед запуском программы. Или можно запустить приложение, остановить его, а затем запустить его снова. Кэшированные данные уже не попадут в новую базу данных.
Теперь при запуске программы у вас каждый раз будет чистая БД. Чтобы отказаться от этого, просто отключите точку останова.

Примечание: Вы только что создали скрипт и написали простую Unix-команду для удаления файла. Также вы можете исполнять PHP скрипт, запускать Java-программу, Python-скрипт, или любую другую программу с помощью свойств точки останова.

Что дальше?

Как вы видите, средства отладки имеют большую гибкость в решении проблем, с которыми вы сталкиваетесь каждый день в процессе разработки. Это дает нам возможность править и тестировать свой код, не беспокоясь о дополнительных ошибках.

Верите или нет, но это только начало. LLDB предоставляет множество других возможностей, таких как пользовательские переменные, динамические точки останова, и даже отладка с помощью Python-скриптов.

Конечно, выход за рамки NSLog-отладки может быть для вас сложным, но, в конце концов, вы сможете сделать ваши проекты лучше.


Какой из указанных материалов RayWenderlich.com вы хотели бы прочитать на русском языке?

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Никто ещё не голосовал. Воздержавшихся нет.

ссылка на оригинал статьи http://habrahabr.ru/post/170343/


Комментарии

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *