Xcode變量概覽-summary

本blog除部分譯文外,全部內容均爲原創,若有雷同,算我抄你:-)html

問題描述

在Xcode中斷點調試時,鼠標停留在變量上,就能看到變量的信息。但對於自定義對象,一般Xcode提供的直接信息很是有限,像這樣
請輸入圖片描述python

想要了解這個對象具體的內容,須要展開左邊的箭頭
請輸入圖片描述git

當開發者想要知道該對象具體某個成員(極可能也是一個對象,即對象的成員的成員.....)的值時,就不得不反覆展開多個箭頭,平添了很多debug時的焦躁=。=github


解決方案

其實LLDB的設計者並不是沒有考慮到這種狀況,他們設計了一種機制,容許在浮動窗口和變量窗口中顯示自定義類型對象的概覽,稱之爲summary。
沒錯,就是浮動窗口上最後一行顯示的summary,咱們再看一次
請輸入圖片描述正則表達式

Summary的原理很簡單,就是保存一個"對象類型->概覽"的映射表,在調試時查表進行顯示。在console中輸入segmentfault

shtype summary list

能夠查看當前LLDB支持的全部語言/平臺的全部類型的summary,好比OC下的NSArrayapp

shtype summary list NSArray

輸出的結果裏,能夠找到
請輸入圖片描述
和日常使用過程當中的狀況一致。ide

LLDB支持爲自定義類型添加summary。

atom

解決示例

直觀起見,這裏將寫一個簡單的對象併爲之添加summary,下面請演員入場spa

objc@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單獨放在一個文件裏

pythondef 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中

shcommand script import /Users/XXX/Desktop/TypeSummaryTest/TypeSummaryTest/summarys.py

P.S:這個命令目測只支持full path,請容許我在這裏可恥地匿了=。=

而後將導入的function指定爲映射便可

shtype summary add Rectangle -F summarys.Rectangle_summary

這時再次查看變量,Summary已經有內容啦:)
請輸入圖片描述

請輸入圖片描述

假若有多個自定義類型的summary,均可以如法炮製。進一步地,可讓Xcode自動加載summary。首先,把加載function這步也寫入腳本

shimport 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文件

shcommand 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

相關文章
相關標籤/搜索