0 added
0 removed
Original
2026-01-01
Modified
2026-03-10
1
<p>Теги: debug, swift, программирование на ios, breakpoint, breakpoint navigator, condition, поиск багов</p>
1
<p>Теги: debug, swift, программирование на ios, breakpoint, breakpoint navigator, condition, поиск багов</p>
2
<p>Первый баг был найден 9 сентября 1945 года. С тех пор их численность увеличилась в разы. Баги заполоняют наши приложения, лишают разработчиков сна, сдвигают сроки сдачи, являются причиной колебания Силы. Пора положить этому конец!</p>
2
<p>Первый баг был найден 9 сентября 1945 года. С тех пор их численность увеличилась в разы. Баги заполоняют наши приложения, лишают разработчиков сна, сдвигают сроки сдачи, являются причиной колебания Силы. Пора положить этому конец!</p>
3
<p>Сегодня я покажу вам, как отлавливать баги в нашем коде, чтобы мы могли выступить против них единым фронтом! Предлагаю включить нумерацию строк в файле - это облегчит навигацию по коду.</p>
3
<p>Сегодня я покажу вам, как отлавливать баги в нашем коде, чтобы мы могли выступить против них единым фронтом! Предлагаю включить нумерацию строк в файле - это облегчит навигацию по коду.</p>
4
<h2>Breakpoint</h2>
4
<h2>Breakpoint</h2>
5
<p><strong>Breakpoint</strong>(точка остановки) - преднамеренное прерывание хода выполнения программы. Благодаря ей мы можем исследовать текущее состояние нашего кода, узнать значения интересующих нас переменных и даже внести изменения без перезапуска приложения.</p>
5
<p><strong>Breakpoint</strong>(точка остановки) - преднамеренное прерывание хода выполнения программы. Благодаря ей мы можем исследовать текущее состояние нашего кода, узнать значения интересующих нас переменных и даже внести изменения без перезапуска приложения.</p>
6
<p><strong>Breakpoint</strong>- это невероятно полезный инструмент для отладки кода. Чтобы создать breakpoint, достаточно просто кликнуть на номере нужной строки.</p>
6
<p><strong>Breakpoint</strong>- это невероятно полезный инструмент для отладки кода. Чтобы создать breakpoint, достаточно просто кликнуть на номере нужной строки.</p>
7
<p>Теперь, когда контроллер загрузится и система вызовет метод viewDidLoad, выполнение программы остановится на выделенной строке. Все установленные breakpoint’ы можно найти во вкладке<strong>Breakpoint Navigator</strong>(нажмите command + 8). Если нажать на breakpoint, его можно сделать неактивным. Здесь мы также можем создать новый breakpoint. Нажмите на знак +:</p>
7
<p>Теперь, когда контроллер загрузится и система вызовет метод viewDidLoad, выполнение программы остановится на выделенной строке. Все установленные breakpoint’ы можно найти во вкладке<strong>Breakpoint Navigator</strong>(нажмите command + 8). Если нажать на breakpoint, его можно сделать неактивным. Здесь мы также можем создать новый breakpoint. Нажмите на знак +:</p>
8
<p>Рассмотрим несколько вариантов: - "Swift Error Breakpoint" - срабатывает при выбросе ошибки заданного типа; - "Exception Breakpoint" - срабатывает при выбросе эксепшена; - "Symbolic Breakpoint" - срабатывает при вызове заданного метода.</p>
8
<p>Рассмотрим несколько вариантов: - "Swift Error Breakpoint" - срабатывает при выбросе ошибки заданного типа; - "Exception Breakpoint" - срабатывает при выбросе эксепшена; - "Symbolic Breakpoint" - срабатывает при вызове заданного метода.</p>
9
<p>Если сейчас открыть Debug Area, то мы увидим два окна: слева - доступные для исследования переменные, справа - консоль, куда мы можем вводить различные команды (об этом чуть позже). Если одно из этих окон не показывается, убедитесь, что в нижнем правом углу нажаты кнопки показа этих окон.</p>
9
<p>Если сейчас открыть Debug Area, то мы увидим два окна: слева - доступные для исследования переменные, справа - консоль, куда мы можем вводить различные команды (об этом чуть позже). Если одно из этих окон не показывается, убедитесь, что в нижнем правом углу нажаты кнопки показа этих окон.</p>
10
<p>Это только начало пути… Чтобы раскрыть остальные скрытые возможности, нажмите правой кнопкой на breakpoint, и выберите "Edit breakpoint..."</p>
10
<p>Это только начало пути… Чтобы раскрыть остальные скрытые возможности, нажмите правой кнопкой на breakpoint, и выберите "Edit breakpoint..."</p>
11
<p>"<strong>Condition</strong>" - условие (булевое выражение), при выполнении которого сработает этот breakpoint; "<strong>Ignore</strong>" - количество раз, сколько нужно проигнорировать срабатывание breakpoint; "<strong>Action</strong>" - действие, которое нужно выполнить.</p>
11
<p>"<strong>Condition</strong>" - условие (булевое выражение), при выполнении которого сработает этот breakpoint; "<strong>Ignore</strong>" - количество раз, сколько нужно проигнорировать срабатывание breakpoint; "<strong>Action</strong>" - действие, которое нужно выполнить.</p>
12
<p>Рассмотрим несколько вариантов: - "<strong>Debugger command</strong>" - команда, которую мы можем ввести в debug-консоли; - "<strong>Log message</strong>" - напечатать в консоль сообщение (@expression@); - "<strong>Options</strong>" - продолжать исполнение программы.</p>
12
<p>Рассмотрим несколько вариантов: - "<strong>Debugger command</strong>" - команда, которую мы можем ввести в debug-консоли; - "<strong>Log message</strong>" - напечатать в консоль сообщение (@expression@); - "<strong>Options</strong>" - продолжать исполнение программы.</p>
13
<h2>Рассмотрим Debug Console (LLDB)</h2>
13
<h2>Рассмотрим Debug Console (LLDB)</h2>
14
<p>Ниже я приведу некоторые полезные команды, которые помогут нам в работе: -<strong>po someObject</strong>- выводится debugDescription объекта; -<strong>p (expression -- ) someObject</strong>- выводится полная информация об объекте.</p>
14
<p>Ниже я приведу некоторые полезные команды, которые помогут нам в работе: -<strong>po someObject</strong>- выводится debugDescription объекта; -<strong>p (expression -- ) someObject</strong>- выводится полная информация об объекте.</p>
15
<p>Мы можем создавать переменные:<strong>p let title = cell.titleLabel?.text; print(title ?? “empty”)</strong>(контекст теряется при выполнении)<strong>p let $title = cell.titleLabel?.text</strong><strong>p print(title ?? “empty”)</strong>(благодаря $ переменная видна во внешнем контексте).</p>
15
<p>Мы можем создавать переменные:<strong>p let title = cell.titleLabel?.text; print(title ?? “empty”)</strong>(контекст теряется при выполнении)<strong>p let $title = cell.titleLabel?.text</strong><strong>p print(title ?? “empty”)</strong>(благодаря $ переменная видна во внешнем контексте).</p>
16
<p>$x переменные можно использовать при задании условий для breakpoint.</p>
16
<p>$x переменные можно использовать при задании условий для breakpoint.</p>
17
<p>Управление исполнением программы: -<strong>Continue</strong>- завершить текущую debug-сессию; -<strong>Step Over</strong>- перейти на следующую строку выполнения программы; -<strong>Step Into</strong>- перейти в контекст текущей строки (если функция, то мы переходим в неё); -<strong>Step Out</strong>- выйти из текущего контекста.</p>
17
<p>Управление исполнением программы: -<strong>Continue</strong>- завершить текущую debug-сессию; -<strong>Step Over</strong>- перейти на следующую строку выполнения программы; -<strong>Step Into</strong>- перейти в контекст текущей строки (если функция, то мы переходим в неё); -<strong>Step Out</strong>- выйти из текущего контекста.</p>
18
<p>Изменения UI:</p>
18
<p>Изменения UI:</p>
19
p let $label = cell.titleLabel! P $label.textColor = Color.red p CATransaction.flush() // Чтобы изменения вступили в силу, не прерывая debug-сессию<p>При нажатии на<strong>Debug View Hierarchy</strong>нам покажется экран с полной иерархией View текущего экрана приложения.</p>
19
p let $label = cell.titleLabel! P $label.textColor = Color.red p CATransaction.flush() // Чтобы изменения вступили в силу, не прерывая debug-сессию<p>При нажатии на<strong>Debug View Hierarchy</strong>нам покажется экран с полной иерархией View текущего экрана приложения.</p>
20
<p>Мы можем выбрать view и как-то его изменить, для этого нам нужен его адрес в памяти.</p>
20
<p>Мы можем выбрать view и как-то его изменить, для этого нам нужен его адрес в памяти.</p>
21
<p>Дальше введём следующие команды в дебаг-консоль: -<strong>e -l swift -- import UIKit</strong>- для начала нужно импортировать UIKit; -<strong>e -l swift -- let $label = unsafeBitCast(0x10bd38f40, to: UILabel.self)</strong>- берём адрес элемента и приводим объект по этому адресу к типу UILabel и сохраняем этот элемент в переменную $label; -<strong>e -l swift -- $label.textColor = UIColor.green</strong>- меняем цвет текста; -<strong>e -l swift -- CATransaction.flush()</strong>- чтобы увидеть изменения сразу; -<strong>e -l swift --</strong>- говорим консоли, что мы хотим работать с языком Swift (по умолчанию Objective-C).</p>
21
<p>Дальше введём следующие команды в дебаг-консоль: -<strong>e -l swift -- import UIKit</strong>- для начала нужно импортировать UIKit; -<strong>e -l swift -- let $label = unsafeBitCast(0x10bd38f40, to: UILabel.self)</strong>- берём адрес элемента и приводим объект по этому адресу к типу UILabel и сохраняем этот элемент в переменную $label; -<strong>e -l swift -- $label.textColor = UIColor.green</strong>- меняем цвет текста; -<strong>e -l swift -- CATransaction.flush()</strong>- чтобы увидеть изменения сразу; -<strong>e -l swift --</strong>- говорим консоли, что мы хотим работать с языком Swift (по умолчанию Objective-C).</p>
22
<p>В этой статье я познакомил вас лишь с малым количеством возможностей, доступных нам для отлавливания багов в нашем коде. Но даже этого багажа может хватить, чтобы облегчить вам жизнь.</p>
22
<p>В этой статье я познакомил вас лишь с малым количеством возможностей, доступных нам для отлавливания багов в нашем коде. Но даже этого багажа может хватить, чтобы облегчить вам жизнь.</p>
23
23