chisel,超牛的Xcode调试工具,慢慢学习

来源:互联网 发布:55海淘 知乎 编辑:程序博客网 时间:2024/06/04 19:25




用Homebrew安装chisel

搞定Homebrew之后,你就可以用他来安装chisel了

官网的命令里有一个brew update,是用来更新Homebrew版本的,如果你是新安装的Homebrew,可以省略掉这条命令

~/.lldbinit中添加命令

安装好之后,terminal中会出现这个东西

意思是需要把这个命令command script import /usr/local/opt/chisel/libexec/fblldb.py加到~/.lldbinit文件中

我们将命令其添加进去即可。如果你已经添加过一次了,不需要再次添加

重启一下Xcode,安装完成

更新

如果你想更新chisel,只需要输入更新的命令即可

命令

Autolayout

autolayout中有一种bug叫Ambiguous Layouts,意思是你设置的约束不足以确定view的位置或大小。比如你只设置了X轴的位置,没有设置Y轴的位置

autolayout提供了专门判断和查找这类问题的方法:

  • hasAmbiguousLayout用于判断是否存在Ambiguous Layouts
  • _autolayoutTrace用于查找存在的Ambiguous Layouts

但是即使有查找的方法,真正去做这个事儿也比较费时费力的,这时候chisel给我们提供了更为方便的命令

alamborder

给存在Ambiguous Layouts的view加上border,方便查找哪些View存在问题

语法:

  • --color/-c: border的颜色,参数为string类型,比如’red’, ‘green’, ‘magenta’等,不设置默认为红色。
  • --width/-w: border的宽度,参数为CGFloat类型,不设置默认宽度为2。

e.g: 假设我们写了这么一段代码,可以明显看出,我们没有设置X轴的位置。

运行代码之后,在LLDB控制台输入alamborder

所有带有Ambiguous Layouts的view立即会被渲染上红色border

可以看到,subview的边框已经变为红色,另外只要有一个View存在Ambiguous Layouts,UIWindow的边框也会变为红色,这就有效的避免了宽度或者高度为0的Ambiguous Layouts不宜察觉的缺陷。

alamunborder

alamborder设置的border去掉.

语法:

e.g: 刚刚设置的border,在lldb控制台输入alamunborder即可去掉边框

paltrace

打印某个View的autolayout详细信息,相当于调用_autolayoutTrace

语法:

  • <view>: 需要打印详细信息的view,不传参数默认为keyWindow

e.g: 查看一下keyWindow上有哪个view存在Ambiguous Layouts

我们可以看到,UIView:0x7ff450d32870存在Ambiguous Layouts,原因是缺少minX。也就是没有设置X轴的位置

Print

在LLDB中,我们执行的最多的可能就是打印操作了,chisel专门为这类操作封装了一些打印命令

pviews

循环打印view层级,正常情况下等效于调用recursiveDescription命令

语法:

  • --up/-u: 以view为起始位置,向上打印,直到打印到window层
  • --depth/-d: 传入int类型,表示打印的层数,0表示没有限制

e.g: 打印一下self.view层级

pvc

循环打印viewController的层级

语法:

<aViewController>: 表示要打印的viewController,不传参数默认viewController为当前的VC

e.g: 打印一下当前VC

pclass

循环打印class的继承关系

语法:

<object>: 要打印继承关系的对象

e.g: 打印一个View对象的继承关系

presponder

打印响应链

语法:

<startResponder>: UIResponder对象,响应链开始位置

e.g: 打印一个tableView的响应链

ptv

打印屏幕中显示的tableView,主要是与pcells联合使用。如果有多个tableView,打印View层级中最上面的一个

语法:

e.g: 看看当前最上面是哪个tableView

pcells

打印tableView中当前可见的cell,如果有多个tableView,打印View层级中最上面的tableView的可见cell

语法:

e.g: 看看当前可见的cell有哪些

pinternals

打印一个对象内部的成员变量,这个方法我一般用来看model属性

语法:

  • <object>: 需要打印内部成员变量的对象

e.g: 我们来看看一个model内部属性的值

pdata

对编码过的NSData进行解码打印,等效于调用-[NSString initWithData:encoding:]

语法:

  • <data>: 需要打印的data,NSData类型
  • --encoding/-e: 编码类型,如果缺省默认为utf8,主要支持的类型有:

e.g: 将一个utf8的NSData打印

pkp

通过-valueForKeyPath:打印key path对应的值。

语法:

  • <keypath>: 需要打印的路径,如self.view

说明:以前打印属性一般都用po obj.xxx,现在我想用pkp obj.xxx是一个更好的选择了,因为po obj.xxx是调用getter方法,如果没有getter方法就无法打印了。pkp obj.xxx不仅会调用getter方法,没有getter方法还会去查找成员变量

e.g: 打印一下self.view

pivar

打印对象成员变量

语法:

  • <object>: id类型,要打印成员变量的对象
  • <ivarName>: 成员变量的名称,注意:如果是属性,对应成员变量的名字默认有_前缀.

说明:个人觉得这个方法有点鸡肋,pinternals一下子可以打印出所有的成员变量,用起来更方便,如果你只想打印某一个成员变量,用pkp应该更爽

e.g: 继续打印self.view

pca

从渲染服务器的角度来打印layer tree,命令的完整名字是PrintCoreAnimationTree,相当于调用po [NSString stringWithCString:(char *)CARenderServerGetInfo(0, 2, 0)]

语法:

说明:这个命令我也没用过,可能在某些情况下会有用处

e.g: 试一下pca

panim

显示是否正在执行动画,相当于调用p (BOOL)[UIView _isInAnimationBlock]

语法:

说明:这个命令也并不常用

e.g: 在动画中,我们打印一下:

Find

debug的时候,我们经常需要查找一些东西,比如View,viewController等。

fvc

根据viewController的Class名字查找VC

语法:

  • --name/-n: string类型参数,根据viewController的Class名字查找viewController
  • --view/-v: UIView类型参数,根据viewController拥有的view查找viewController

说明:上面2个option不能同时使用,只能使用某一个

e.g: 我们先根据名字查找一下VC

e.g: 如果我们知道VC的view地址,也可以根据view来查找VC

fv

根据view的class名字查找view

语法:

  • <classNameRegex>: view的class名称

e.g: 查找一下屏幕上的UILabel

taplog

将点击的view打印出来,这个命令对于查找哪个view非常有帮助

语法:

说明:要查看的view必须能接收点击事件,也就是他的userInteractionEnabled必须为YES才能被找到,UILabel和UIImageView默认userInteractionEnabled为NO。

用法:我们需要先将程序暂停,输入taplog,程序会自己运行,这时候点击你需要查看的view,控制台上就会显示出你刚刚点击的view相关信息

e.g: 我们先将程序暂停,输入taplog

程序会自己运行,我们再点击一个UIButton:

flicker

将view闪烁一下,以便于查找view的位置

语法:

  • <viewOrLayer>需要闪烁的view或者layer

e.g: 我们来看看self.subView的位置

vs

在view层级中搜索view,并显示出来

语法:

  • <view>:要查找的view

说明:相比fvvs主要用于显示view在屏幕上的位置,2个命令可以配合使用

e.g: 假设我们要找屏幕上的一个view

首先用fv查找UIView类型的view

然后看看这2个view到底哪个是我们想要找的view

输入命令后他会帮我们在屏幕上用粉红色标志出来vs的view

控制台中vs的view也有相应log。并且还提示有6种子命令:

  • w: 移动到superview
  • s: 移动到第一个subview
  • a: 移动到前面的同级view
  • d: 移动到后面的同级view
  • p: 打印出层级
  • q: 退出

如果这个不是我们要找的view,可以使用w,s,a,d,p命令继续查找

Display

debug的时候,可能有一小半的工作是跟UI打交道,关于UI显示上的东西,也有几个命令

caflush

刷新UI界面。一般我们用LLDB命令改变UI,UI并不会立即更新,我们需要使用caflush刷新界面

语法:

e.g: 我们用命令将label的背景色改为红色

border

给View或者layer加上border

语法:

  • --color/-c: 边框颜色,string类型,比如:’red’, ‘green’ ‘magenta’等,不设置默认为红色
  • --width/-w: 边框宽度,不设置默认为2
  • <viewOrLayer>: 需要设置边框的view或者layer

e.g: 给刚刚的label加上边框

unborder

去掉view或者layer的border

语法:

e.g: 将刚刚加上的border去掉

mask

给view添加一个半透明的矩形mask,用来查看view的位置

语法:

  • --color/-c: mask的颜色,string类型,比如:’red’, ‘green’,’magenta’等,不设置默认为红色
  • --alpha/-a: mask的透明度,不设置默认为0.5
  • <viewOrLayer>: 需要添加mask的view或者layer

e.g: 假如label是隐藏的,我们给他添加一个mask,看看他的位置在哪儿

unmask

将添加的mask去掉

语法:

  • <viewOrLayer>: 需要去掉mask的view或者layer

e.g: 我们将刚刚添加的mask去掉

使用命令之后,我们可以看到什么都没有了,因为label是hidden的

show

显示一个view或者layer,相当于执行view.hidden = NO

语法:

  • <viewOrLayer>: 需要显示的view或者layer

e.g: 将刚刚的label显示出来

hide

隐藏一个view或者layer,相当于执行view.hidden = YES

语法:

  • <viewOrLayer>: 需要隐藏的view或者layer

e.g: 又把label隐藏

可以看到label位置什么都没有了

slowanim

减慢动画的速度

语法:

  • <speed>: 动画的速度,速度越大,动画越快。1表示原始速度。不传参数默认为0.1

e.g: 原始动画我们设置为1s

暂停程序,将动画放慢5倍

我们可以看到动画变慢了:

unslowanim

取消slowanim效果,将动画速度变为正常

语法:

e.g: 我们将刚刚的slowanim效果取消

Preview

预览功能,帮助我们用命令查看一个view或者图片的真正样子

visualize

用预览App打开UIImage, CGImageRef, UIView, CALayer等对象

语法:

  • <target>: 需要预览的对象,id类型

e.g: 我们来看看某个image的样子

Debug

LLDB主要用于Debug,chisel怎么可能缺少debug相关命令呢?

wivar

为对象的成员变量设置watchpoint,更多watchpoint相关知识请阅读<小笨狼与LLDB的故事>

语法:

  • <object>: 需要为成员变量设置watchpoint的对象。id类型
  • <ivarName>: 成员变量的名字,注意一般属性对应的成员变量带有_前缀

e.g: 为self.subView设置watchpoint

这时候,_subView值改变就会中断程序

bmessage

根据方法名设置断点

语法:

  • <expression>: 设置断点的方法名,如: -[MyView setFrame:]+[MyView awesomeClassMethod]-[0xabcd1234 setFrame:]

说明:一般设置断点,如果这个方法本类没有实现,是父类实现的,断点是无效的。bmessage有效避免了这种缺陷,即使本类没有实现,也能设置上断点

e.g: 给self中的btnAction:方法设置一个断点

binside

通过一个相对地址,给framework(library)设置断点

语法:

  • <address>: framework的相对地址

pinvocation

打印方法调用堆栈,仅支持x86

语法:

  • --all/-a: 表示打印所有堆栈,不设置默认只打印当前堆栈

说明:与bt命令类似,不过信息比bt打印得更详细,遗憾的是只能支持x86

e.g: 打印一下当前堆栈

打印所有堆栈:

Accessibility

这个模块的命令主要利用了UIAccessibility相关特性,需要开启Accessibility功能才能使用,UIAccessibility详细资料可以阅读UIAccessibility

fa11y

根据view的accessibilityLabel查找view

语法:

  • <labelRegex>: 需要匹配的text

说明:UILabel,UIButton的accessibilityLabel等于title

e.g: 我们根据显示的文案,查找相应的控件

pa11y

打印view层级中所有的accessibilityLabel

语法:

  • <aView>: 需要打印层级的View,UIView类型

e.g: 我们打印一下self.view层级中所有的accessibilityLabel

End

chisel的命令就介绍到这里,东西挺多的,没必要全部都记住,我把这个写出来就打算当做一个文档,以后记不起哪个命令就查一下自己的博客。

不过chisel确实是个好东西,工欲善其事,必先利其器。要想要方便的调bug,chisel绝对值得你拥有




原文链接: http://ios.jobbole.com/83589/

GitHub:    https://github.com/gkassabli/chisel


原创粉丝点击