Остановись, мгновение: ловим баги с Breakpoint и Debug Console (LLDB)
Первый баг был найден 9 сентября 1945 года. С тех пор их численность увеличилась в разы. Баги заполоняют наши приложения, лишают разработчиков сна, сдвигают сроки сдачи, являются причиной колебания Силы. Пора положить этому конец!
Сегодня я покажу вам, как отлавливать баги в нашем коде, чтобы мы могли выступить против них единым фронтом! Предлагаю включить нумерацию строк в файле — это облегчит навигацию по коду.
Breakpoint
Breakpoint (точка остановки) — преднамеренное прерывание хода выполнения программы. Благодаря ей мы можем исследовать текущее состояние нашего кода, узнать значения интересующих нас переменных и даже внести изменения без перезапуска приложения.
Breakpoint — это невероятно полезный инструмент для отладки кода. Чтобы создать breakpoint, достаточно просто кликнуть на номере нужной строки.
Теперь, когда контроллер загрузится и система вызовет метод
Рассмотрим несколько вариантов: — «Swift Error Breakpoint» — срабатывает при выбросе ошибки заданного типа; — «Exception Breakpoint» — срабатывает при выбросе эксепшена; — «Symbolic Breakpoint» — срабатывает при вызове заданного метода.
Если сейчас открыть Debug Area, то мы увидим два окна: слева — доступные для исследования переменные, справа — консоль, куда мы можем вводить различные команды (об этом чуть позже). Если одно из этих окон не показывается, убедитесь, что в нижнем правом углу нажаты кнопки показа этих окон.
Это только начало пути… Чтобы раскрыть остальные скрытые возможности, нажмите правой кнопкой на breakpoint, и выберите «Edit breakpoint...»
«Condition» — условие (булевое выражение), при выполнении которого сработает этот breakpoint; «Ignore» — количество раз, сколько нужно проигнорировать срабатывание breakpoint; «Action» — действие, которое нужно выполнить.
Рассмотрим несколько вариантов: — «Debugger command» — команда, которую мы можем ввести в debug-консоли; — «Log message» — напечатать в консоль сообщение (@expression@); — «Options» — продолжать исполнение программы.
Рассмотрим Debug Console (LLDB)
Ниже я приведу некоторые полезные команды, которые помогут нам в работе: — po someObject — выводится debugDescription объекта; — p (expression -- ) someObject — выводится полная информация об объекте.
Мы можем создавать переменные: p let title = cell.titleLabel?.text; print(title ?? “empty”) (контекст теряется при выполнении) p let $title = cell.titleLabel?.text p print(title ?? “empty”) (благодаря $ переменная видна во внешнем контексте).
$x переменные можно использовать при задании условий для breakpoint.
Управление исполнением программы: — Continue — завершить текущую debug-сессию; — Step Over — перейти на следующую строку выполнения программы; — Step Into — перейти в контекст текущей строки (если функция, то мы переходим в неё); — Step Out — выйти из текущего контекста.
Изменения UI:
p let $label = cell.titleLabel! P $label.textColor = Color.red p CATransaction.flush() // Чтобы изменения вступили в силу, не прерывая debug-сессию
При нажатии на Debug View Hierarchy нам покажется экран с полной иерархией View текущего экрана приложения.
Мы можем выбрать view и как-то его изменить, для этого нам нужен его адрес в памяти.
Дальше введём следующие команды в дебаг-консоль: — e -l swift -- import UIKit — для начала нужно импортировать UIKit; — e -l swift -- let $label = unsafeBitCast(0x10bd38f40, to: UILabel.self) — берём адрес элемента и приводим объект по этому адресу к типу UILabel и сохраняем этот элемент в переменную $label; — e -l swift -- $label.textColor = UIColor.green — меняем цвет текста; — e -l swift -- CATransaction.flush() — чтобы увидеть изменения сразу; — e -l swift -- — говорим консоли, что мы хотим работать с языком Swift (по умолчанию Objective-C).
В этой статье я познакомил вас лишь с малым количеством возможностей, доступных нам для отлавливания багов в нашем коде. Но даже этого багажа может хватить, чтобы облегчить вам жизнь.