Советы по отладке
Вот несколько моих любимых трюков и советов по отладке, которые я использую при работе над проектами Swift.
Настройте свой .lldbinit
Во-первых, большинство из нас хотят работать со Swift, а не с Objective-C, но в зависимости от настроек вашего проекта у вас по умолчанию может быть включен Objective-C. У нас есть 2 варианта:
- Мы можем вручную изменить язык во время сеанса lldb, вызвав settings set target.language swift
- Мы можем создать файл .lldbinit в нашем домашнем каталоге и добавить его туда по умолчанию для всех сеансов отладки, например: echo 'Settings set target.language swift' > ~/.lldbinit, за которым следует chmod +x ~/.lldbinit
Кроме того, .lldbinit — отличное место для добавления дополнительных вещей, которые вы будете использовать в своих проектах. Вот часть моих:
settings set target.language swift
breakpoint set -r NSWindow.initialFirstResponder --one-shot true --auto-continue true
breakpoint command add
e import AppKit
e import Foundation
e func $vc<T>(_ input: T) -> NSViewController { unsafeBitCast(input, to: NSViewController.self) }
e func $view<T>(_ input: T) -> NSView { unsafeBitCast(input, to: NSView.self) }
DONE
breakpoint set -n UIApplicationMain --one-shot true --auto-continue true
breakpoint command add
e import UIKit
e import Foundation
e func $vc<T>(_ input: T) -> UIViewController { unsafeBitCast(input, to: UIViewController.self) }
e func $view<T>(_ input: T) -> UIView { unsafeBitCast(input, to: UIView.self) }
DONE
Это позволяет мне использовать адрес памяти, чтобы легко получить информацию о моих типах:
po $vc(0x128027ad400)
Примечания:
- Использование $ для имен переменных и функций — это то, как мы получаем эти вещи, доступные за пределами только текущего контекста выражения, от Apple:
- Мы настраиваем начальный брейкпоинт (точка останова или точка прерывания) как триггер для добавления новых функций в систему. В противном случае они не будут работать, поскольку выражения не оцениваются как часть инициализации lldb из-за отсутствия кадров стека.
- Я работаю как в контексте Mac, так и в iOS, поэтому я устанавливаю 2 отдельных брейкпоинта и варианты общих функций, которые я использую.
Используйте переменные фрейма
Большинство разработчиков Swift привыкли использовать print object или сокращенно po, но есть альтернатива, которая часто работает быстрее и работает в тех случаях, когда po может не сработать: frame variable или v
Короткий псевдоним был добавлен еще в Xcode 10.2, и вот примечание Apple об этом.
🤔 v и vo работают для сохраненных свойств, но не будут работать для вычисляемых. Вам понадобится po для них.
Вот пример:
Вы можете добавить к нему дополнительные флажки, как например опцию -O, чтобы получить еще больше информации.
Используйте выражения
Вышеупомянутый po — это псевдоним для e -O -, который оценит объект и попытается вызвать для него метод description, если он существует, он оценит данное выражение, а затем попытается вызвать для него метод description.
Но выражения более ценны, и было бы целесообразно использовать их напрямую, а не полагаться на po.
Мы можем взаимодействовать с нашей системой, используя e или expression, это может быть очень удобно при работе с переменными:
e var $vc = self.controller
e $vc.view.layer.borderColor = CGColor.red
e CATransation.flush() // Refresh the core animation screen without having to end debugging session
Наблюдайте за системой
Мы можем использовать брейкпоинты для многих вещей, от изменения вводимых (*входных) данных по умолчанию в поля (например, формы входа):
До использования команд отладчика для создания цепочек символических брейкпоинтов, например:
breakpoint set --name "[CommandBarInputContainer layout]"
создавал бы точку останова при вызове макета моего NSView. Это происходило бы слишком часто, но я бы мог установить её как часть выполнения другого брейкпоинта, например, когда пользователь меняет ввод текста.
Я также мог бы использовать --one-shot true, чтобы точка останова выполнялась только один раз для каждого триггера.
Наблюдайте за изменением переменной
Мы можем добавить брейкпоинты при изменении переменной либо с помощью пользовательского интерфейса Xcode, либо с помощью команды lldb:
watchpoint set variable self.homeViewController
UI Точки наблюдения
Затем всякий раз, когда эта переменная изменяется, Xcode останавливает наш сеанс отладки и предоставляет нам такую информацию:
Затем мы можем распечатать и взаимодействовать с этим значением
po value
▿ Optional<NSViewController>
▿ some : <HomeButton.HomeViewController: 0x13407cf3ac0>
Какие ваши любимые?
Дайте мне знать, какие у вас любимые советы или команды lldb!