問題描述
在Xcode中斷點除錯時,滑鼠停留在變數上,就能看到變數的資訊。但對於自定義物件,通常Xcode提供的直接資訊非常有限,像這樣
想要了解這個物件具體的內容,需要展開左邊的箭頭
當開發者想要知道該物件具體某個成員(很可能也是一個物件,即物件的成員的成員.....)的值時,就不得不反覆展開多個箭頭,平添了不少debug時的焦躁=。=
解決方案
其實LLDB的設計者並非沒有考慮到這種情況,他們設計了一種機制,允許在浮動視窗和變數視窗中顯示自定義型別物件的概覽,稱之為summary。
沒錯,就是浮動視窗上最後一行顯示的summary,我們再看一次
Summary的原理很簡單,就是儲存一個"物件型別->概覽"的對映表,在除錯時查表進行顯示。在console中輸入
type summary list
可以檢視當前LLDB支援的所有語言/平臺的所有型別的summary,比如OC下的NSArray
type summary list NSArray
輸出的結果裡,可以找到
和平常使用過程中的情況一致。
LLDB支援為自定義型別新增summary。
解決示例
直觀起見,這裡將寫一個簡單的物件併為之新增summary,下面請演員入場
@interface Rectangle : NSObject
{
NSInteger _width;
NSInteger _height;
}
@property (nonatomic, assign) NSInteger width;
@property (nonatomic, assign) NSInteger height;
@end
對於這個矩形類的例項,我希望能夠直接看到它的面積。
Summary可以簡單地設定物件的概覽為靜態字串,也可以設定為動態的如正規表示式,甚至可以設定為Python function(事實上LLDB就是使用了Python作為對映的)。
在這裡,嗯。。。。。Python,就決定是你啦!
方便起見不直接在console裡寫入,而是把function單獨放在一個檔案裡
def Rectangle_summary (valobj,internal_dict):
height_val = valobj.GetChildMemberWithName('_height')
width_val = valobj.GetChildMemberWithName('_width')
height = height_val.GetValueAsUnsigned(0)
width = width_val.GetValueAsUnsigned(0)
area = height*width
return 'Area: ' + str(area)
儲存成summarys.py
儲存起來而不是直接在console裡寫,將來就可以方便地新增其他自定義型別的summary,也可以將這個檔案和開發組的成員共享:)
接下來匯入到LLDB中
command script import /Users/XXX/Desktop/TypeSummaryTest/TypeSummaryTest/summarys.py
P.S:這個命令目測只支援full path,請允許我在這裡可恥地匿了=。=
然後將匯入的function指定為對映即可
type summary add Rectangle -F summarys.Rectangle_summary
這時再次檢視變數,Summary已經有內容啦:)
假如有多個自定義型別的summary,都可以如法炮製。進一步地,可以讓Xcode自動載入summary。首先,把載入function這步也寫入指令碼
import lldb
def Rectangle_summary (valobj,internal_dict):
height_val = valobj.GetChildMemberWithName('_height')
width_val = valobj.GetChildMemberWithName('_width')
height = height_val.GetValueAsUnsigned(0)
width = width_val.GetValueAsUnsigned(0)
area = height*width
return 'Area: ' + str(area)
def __lldb_init_module(debugger, dict):
debugger.HandleCommand('type summary add Rectangle -F summarys.Rectangle_summary')
然後,讓Xcode在啟動時自動匯入這個檔案。在~/下新建一個.lldbinit檔案,並在其中寫入command script import來匯入summary檔案
command script import /Users/XXX/Desktop/TypeSummaryTest/TypeSummaryTest/summarys.py
.lldbinit這個技巧來自於Facebook的chisel,是一個FB擴充套件的LLDB命令集
That's all for today, have fun~
參考資料
LLDB Tutorial
LLDB Data Formatters
Advanced Debugging with LLDB
LLDB Python Reference