Если я спрошу, какую команду LLDB вы используете чаще всего, то я почти уверен, что вы, как и большинство iOS-разработчиков, ответите po. Но знали ли вы, что вы можете определить свою собственную команду LLDB, используя только Swift-код?

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

  • Добавим вашу первую команду LLDB

  • Добавим команду LLDB с аргументами

  • Преобразуем сложный Swift-код  в команду LLDB

Без лишних разглагольствований, давайте приступим к делу!

Добавление вашей первой команды LLDB

Немного о структуре команды LLDB

Чтобы добавить пользовательскую команду LLDB, мы должны использовать команду LLDB command alias. Она имеет следующую структуру:

command alias [command_name] expr -l Swift -O -- [swift_code]

Давайте разберем приведенную выше команду:

  • command alias: команда LLDB, которая формирует из указанного Swift-кода пользовательскую команду с указанным именем.

  • [command_name]: указываемое имя пользовательской команды.

  • expr -l Swift -O --: так мы просим отладчик LLDB интерпретировать все последующее как Swift-код.

  • [swift_code]: Swift-код, определяющий логику пользовательской команды.

Например, если мы хотим добавить пользовательскую команду под названием greet, которая выводит “Hello World!” в консоль, то эта команда LLDB будет выглядеть примерно так:

command alias greet expr -l Swift -O -- print("Hello World!")

Добавление пользовательской команды

Теперь, когда мы сформировали команду alias для greet, нам нужно добавить ее в отладчик LLDB.

Самый простой способ добавить команду greet в отладчик LLDB заключается в том, чтобы просто выполнить сформированную нами команду alias в консоли Xcode.

Выполнение-команды alias в консоли Xcode
Выполнение-команды alias в консоли Xcode

Однако этот подход делает команду greet доступной для использования только в этом конкретном сеансе отладки. Другими словами, нам нужно будет повторно вводить одну и ту же команду alias каждый раз, когда мы начинаем новый сеанс отладки.

Чтобы избежать подобной мороки, мы можем использовать .lldbinit-файл, расположенный в корневом каталоге. Обратите внимание, что это скрытый файл, и если вы не видите этот файл, то вы можете использовать следующий шорткат, чтобы отобразить скрытые файлы в вашем файндере: shift + command + .

Если вы разрешили файндеру отображать скрытые файлы, но все еще не можете найти этот файл, создайте его в своем корневом каталоге, используя в терминале следующую команду:

touch ~/.lldbinit

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

Профессиональная рекомендация:

Если вам не нравится идея перезапускать сеанс отладки каждый раз после обновления .lldbinit-файл, вы можете перезагрузить его с помощью следующей команды:

command source ~/.lldbinit


Добавление команды LLDB с аргументами

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

На этот раз мы воспользуемся командой LLDB command regex. Она имеет следующую структуру:

command regex [command_name] 's/[regex]/expr -l Swift -O -- [swift_code]/'

Я не буду вдаваться в подробности того, как работает команда regex, так как это выходит за рамки этой статьи. Как правило, все, что вам нужно сделать, это заменить [regex] на следующую конструкцию регулярного выражения (.+), а затем использовать %1 для представления аргумента в Swift-коде.

Разобравшись с этим, мы теперь можем обновить команду greet соответствующим образом, а именно:

command regex greet 's/(.+)/expr -l Swift -O -- print("Hello (%1)!")/'

Вот как команда greet будет выглядеть в действии после внесенных изменений (при условии, что name = "Swift Senpai"):

(lldb) greet name
Hello Swift Senpai!

На этом этапе вы можете спросить: а что, если мне нужно передать более одного аргумента? Ответ на самом деле довольно прост.

Во-первых, вам просто нужно добавить больше (.+) в конструкцию регулярного выражения и отделить каждый (.+) пробелом. После этого используйте %2, %3, %4 и т.д. для представления каждого аргумента в Swift-коде в порядке их указания.

Давай попробуем изменить нашу команду greet, чтобы теперь она принимала два аргумента:

command regex greet 's/(.+) (.+)/expr -l Swift -O -- print("Hello (%1) and (%2)!")/'

Когда будете использовать эту команду, просто разделите каждый аргумент пробелом, например так (при условии, что name1 = "Swift Senpai" и name2 = "iOS developers"):

(lldb) greet name1 name2
Hello Swift Senpai and iOS developers!

Вот так просто можно добавить пользовательскую команду LLDB, которая принимает несколько аргументов. В следующем разделе я покажу вам, как преобразовать функцию Swift из нескольких строк в пользовательскую команду LLDB.


Преобразование сложного Swift-кода в команду LLDB

Одним из ограничений при добавлении пользовательского Swift-кода в качестве команды LLDB является то, что все должно быть сделано в одну строку. Поэтому, если у нас есть многострочная функция Swift, мы должны сначала преобразовать ее в однострочную, и только после этого мы можем добавлять ее в .lldbinit-файл.

Допустим, мы хотим добавить следующую функцию Swift, которая преобразует RGB в шестнадцатеричное значение:

func hex(r: Int, g: Int, b: Int) {

    /* Убедитесь, что значение RGB находится в пределах допустимого диапазона /
    if (r >= 0 && r <= 255) && (g >= 0 && g <= 255) && (b >= 0 && b <= 255) {

        let rgb:Int = r<<16 | g<<8 | b<<0
        let hex = String(format:"#%06x", rgb)

        print(hex)
    } else {
        print("Invalid input value")
    }
}

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

Кроме того, прежде чем мы сможем преобразовать наш Swift-код в одну строку, нам также нужно внести в него несколько изменений. Вот что нам нужно сделать:

  1. Определить переменную для каждого параметра функции.

  2. Назначать%1, %2, %3 и т.д. для каждой определенной переменной.

  3. Добавлять ; в конце каждого выражения.

Вот как будет выглядеть наш Swift-код после выполнения всеъ этих корректировок:

let r = %1;
let g = %2;
let b = %3;

/ Убедитесь, что значение RGB находится в пределах допустимого диапазона */
if (r >= 0 && r <= 255) && (g >= 0 && g <= 255) && (b >= 0 && b <= 255) {

    let rgb:Int = r<<16 | g<<8 | b<<0;
    let hex = String(format:"#%06x", rgb);

    print(hex);
} else {
    print("Invalid input value");
}

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

Как только мы преобразуем наш Swift-код в одну строку, мы можем сформировать команду regex следующим образом:

command regex hex 's/(.+) (.+) (.+)/expr -l Swift -O -- let r = %1; let g = %2; let b = %3; if (r >= 0 && r <= 255) && (g >= 0 && g <= 255) && (b >= 0 && b <= 255) { let rgb:Int = r<<16 | g<<8 | b<<0; let hex = String(format:"#%06x", rgb); print(hex); } else { print("Invalid input value"); }/'

Теперь можно смело добавлять команду в .lldbinit-файл, после чего она станет полность готовой к использованию.

Преобразование RGB в шестнадцатеричное значение с помощью пользовательской команды LLDB
Преобразование RGB в шестнадцатеричное значение с помощью пользовательской команды LLDB

Полезные пользовательские команды LLDB

Отлично, мы разобрались, как добавить пользовательскую команду в отладчик LLDB, но теперь настало время понять какую же именно пользовательскую команду LLDB имеет смысл добавлять?

Лично я нахожу особенно полезной следующую пользовательскую команду. Это команда, которая выводит pretty print форму любого JSON-сериализуемого типа, такого как Dictionary, Array, Data и т.д. в виде JSON-строки в консоли Xcode. Больше об этом вы можете узнать здесь.

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

Заключение

Эта статья лишь вскользь затрагивает возможности отладчика LLDB. Если вы новичок в LLDB, я надеюсь, что эта статья вдохновит вас начать изучение этого замечательного инструмента отладки, начиная с сегодняшнего дня.

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


Приглашаем на открытое занятие «Поддержка многоязычности в приложениях iOS», которое пройдет в рамках онлайн-курса "iOS Developer. Professional". Все желающие могут записаться по ссылке.

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