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

相关文章
相关标签/搜索