Вот несколько моих любимых трюков и советов по отладке, которые я использую при работе над проектами 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
Watchpoint UI
Watchpoint UI

Затем всякий раз, когда эта переменная изменяется, Xcode останавливает наш сеанс отладки и предоставляет нам такую информацию:

Затем мы можем распечатать и взаимодействовать с этим значением:

po value
▿ Optional<NSViewController>
  ▿ some : <HomeButton.HomeViewController: 0x13407cf3ac0>

Какие ваши любимые?

Дайте мне знать, какие у вас любимые советы или команды lldb!

Комментарии (1)


  1. DevlabStudio
    03.12.2022 12:18
    +1

    Отличное руководство по отладке в консоли, только не все используют