如何將 Swift 代碼添加為自定義 LLDB 命令
譯者:展菲
原文鏈接:Adding Swift Code as Custom LLDB Command[1]
1. 前言
如果問你最常使用哪個 LLDB 命令?我相信大多數 iOS 開發者都會回答 po。那你是否知道可以使用純 Swift 代碼自定義屬于自己的 LLDB 命令呢?
本文分享如何創建自己的 LLDB 命令。以下是將要分享的內容:
- 添加你的第一個 LLDB 命令
- 添加帶參數的 LLDB 命令
- 將復雜的 Swift 代碼轉換為 LLDB 命令
2. 添加您的第一個 LLDB 命令
2.1 了解 LLDB 命令結構
為了添加自定義 LLDB 命令,我們必須利用 command alias LLDB 命令。它結構如下:
- command alias [command_name] expr -l Swift -O -- [swift_code]
對命令進行詳細分解:
- command alias:使用名稱為 Swift 代碼添加別名的 LLDB 命令
- [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!")
2.2 添加自定義命令
現在已經構造了別名為 greet 的命令,然后添加到 LLDB 調試器中。
將 greet 命令添加到 LLDB 調試器的最直接方法是在 Xcode 控制臺中執行別名命令。

但是,這樣做只會使 greet 命令在當前特定調試會話中可用。也就是說,每當開始新的調試會話時,我們就需要重新鍵入相同的別名命令。
為了避免這種情況發生,我們可以利用位于主目錄中的 .lldbinit 文件。 請注意,這是一個隱藏文件,如果看不到該文件,可以使用以下快捷方式在你的查找器中顯示隱藏文件:
- shift + command + .
如果在 finder 中啟用了顯示隱藏文件,仍然沒有找到該文件,可以在根目錄下使用下面的終端命令創建一個:
- touch ~/.lldbinit
之后,打開 .lldbinit 文件將整個別名命令粘貼到文件中。這樣,Xcode 將在每次啟動新的調試會話時執行別名命令。
- Pro Tip: 如果不想在每次更新 .lldbinit 文件時都重新啟動調試會話,可以使用以下命令重新加載它:
- command source ~/.lldbinit
3. 添加帶參數的 LLDB 命令
接著,讓我們嘗試添加一個能夠接受參數的命令。在上面 greet 命令的基礎上進行修改,使其能夠接受一個字符串并且打印出問候消息。
這一次,我們將使用 command regex LLDB 命令。它結構如下:
- command regex [command_name] 's/[regex]/expr -l Swift -O -- [swift_code]/'
這里對 regex 命令的工作原理不做詳細描述。通常,是將 [regex] 替換為正則表達式語句 (.+),然后在 Swift 代碼中使用 %1 表示參數。
更新 greet,如下所示:
- command regex greet 's/(.+)/expr -l Swift -O -- print("Hello \(%1)!")/'
假設 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 命令。
4. 函數轉換為 LLDB 命令
通過前面的介紹,我們知道添加自定義 Swift 代碼作為 LLDB 命令,必須在一行中完成。因此,如果有一個多行的 Swift 函數,我們必須先將其轉換為單行,然后才能將其添加到 .lldbinit 文件中。
比如要添加下面這個將 RGB 值轉換為十六進制值的 Swift 函數:
- func hex(r: Int, g: Int, b: Int) {
- /* Make sure RGB value within range */
- 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、%3... 分配給每個定義的變量。
- 在每個語句的末尾添加 ;。
更新后的 Swift 代碼如下:
- let r = %1;
- let g = %2;
- let b = %3;
- /* Make sure RGB value within range */
- 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 代碼轉換為一行,我比較喜歡使用這個免費在線工具[2]進行單行轉換
將代碼轉換為單行后,就可以進行構造正則表達式命令:
- 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 文件中,然后就可以使用了。

5. 實用的自定義 LLDB 命令
在學會了如何向 LLDB 調試器中添加自定義命令,那么添加什么樣的自定義 LLDB 命令最實用呢?
我個人認為下面的自定義命令非常實用。可以在 Xcode 控制臺中將任何 JSON 可序列化類型(例如字典、數組、數據等)打印為 JSON 字符串。可以參考這篇文章[3]。
另外,我也很喜歡本文[4]討論的一系列自定義命令,我們可以使用它們來動態修改 UI 元素的顏色,而無需重新構建項目。
6. 總結
本文只是對 LLDB 調試器功能做了簡單介紹。如果你是剛剛接觸到 LLDB,希望這篇文章能幫助你開始探索這個神奇的調試工具。
參考資料
[1] Adding Swift Code as Custom LLDB Command:
https://swiftsenpai.com/testing/add-custom-lldb/
2] 代碼單行轉換工具:
https://www.textfixer.com/tools/paragraph-to-lines.php
[3] Debugging JSON Data in LLDB:
https://soffes.blog/debugging-json-data-in-lldb
[4] Modifying UI elements with Xcode and LLDB v2:
https://diamantidis.github.io/2018/10/14/modifying-ui-elements-with-xcode-and-lldb-v2
本文轉載自微信公眾號「Swift 社區 」,可以通過以下二維碼關注。轉載本文請聯系Swift 社區 公眾號。