安裝
在終端輸入命令
brew update
brew install chisel
如果沒(méi)有安裝brew的話肝匆,會(huì)報(bào)出-bash: brew: command not found
錯(cuò)誤匹中,需要先安裝brew
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
然后參照終端上輸出的
Add the following line to ~/.lldbinit to load chisel when Xcode launches:
command script import /usr/local/opt/chisel/libexec/fblldb.py
將command script import /usr/local/opt/chisel/libexec/fblldb.py
添加到~/.lldbinit中(如果沒(méi)有使用命令touch ~/.lldbinit
創(chuàng)建)恰画,然后重啟Xcode才能使用chisel傀顾。
重啟Xcode后靡羡,通過(guò)help命令可以看到多出了很多新的命令犀盟,就是chisel中的
Current user-defined commands:
alamborder -- For more information run 'help alamborder'
alamunborder -- For more information run 'help alamunborder'
binside -- For more information run 'help binside'
bmessage -- For more information run 'help bmessage'
border -- For more information run 'help border'
caflush -- For more information run 'help caflush'
dcomponents -- For more information run 'help dcomponents'
eobjc -- For more information run 'help eobjc'
eswift -- For more information run 'help eswift'
fa11y -- For more information run 'help fa11y'
flicker -- For more information run 'help flicker'
fv -- For more information run 'help fv'
fvc -- For more information run 'help fvc'
hide -- For more information run 'help hide'
mask -- For more information run 'help mask'
mwarning -- For more information run 'help mwarning'
pa11y -- For more information run 'help pa11y'
pactions -- For more information run 'help pactions'
paltrace -- For more information run 'help paltrace'
panim -- For more information run 'help panim'
pca -- For more information run 'help pca'
pcells -- For more information run 'help pcells'
pclass -- For more information run 'help pclass'
pcomponents -- For more information run 'help pcomponents'
pcurl -- For more information run 'help pcurl'
pdata -- For more information run 'help pdata'
pdocspath -- For more information run 'help pdocspath'
pinternals -- For more information run 'help pinternals'
pinvocation -- For more information run 'help pinvocation'
pivar -- For more information run 'help pivar'
pjson -- For more information run 'help pjson'
pkp -- For more information run 'help pkp'
pmethods -- For more information run 'help pmethods'
pobjc -- For more information run 'help pobjc'
poobjc -- For more information run 'help poobjc'
poswift -- For more information run 'help poswift'
presponder -- For more information run 'help presponder'
pswift -- For more information run 'help pswift'
ptv -- For more information run 'help ptv'
pvc -- For more information run 'help pvc'
pviews -- For more information run 'help pviews'
rcomponents -- For more information run 'help rcomponents'
show -- For more information run 'help show'
slowanim -- For more information run 'help slowanim'
taplog -- For more information run 'help taplog'
unborder -- For more information run 'help unborder'
unmask -- For more information run 'help unmask'
unslowanim -- For more information run 'help unslowanim'
visualize -- For more information run 'help visualize'
vs -- For more information run 'help vs'
wivar -- For more information run 'help wivar'
For more information on any command, type 'help <command-name>'.
常用命令介紹
alamborder&alamunborder
如果給一個(gè)view添加了約束拣度,但是該約束不足以確定它的位置碎绎,使用alamborder命令可以給其添加邊框,常使用autolayout的話抗果,該命令會(huì)很實(shí)用筋帖。通過(guò)help alamborder
可以看到它的語(yǔ)法是Syntax: alamborder [--color=color] [--width=width]
顏色默認(rèn)是紅色,寬度2冤馏,我試了幾次alamborder [--color=green][--width=2]
發(fā)現(xiàn)顏色和寬度都是默認(rèn)的日麸,也沒(méi)研究出來(lái)是哪里出錯(cuò)了。
例子逮光,我給一個(gè)button添加了約束
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.backgroundColor = [UIColor grayColor];
[btn setTitle:@"按鈕" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
[btn mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.offset(10);
make.height.equalTo(@(50));
}];
可以看到約束不能確定button的x點(diǎn)和寬度代箭,使用alamborder命令,即可看到button被添加了紅色的邊框涕刚,同時(shí)UIWindow的也被加了邊框嗡综,好像是只要存在子view約束不完整,UIWindow也會(huì)被加上邊框杜漠。
效果如下圖:
alamunborder和alamborder相反极景,該命令用于把a(bǔ)lamborder設(shè)置的邊框去掉
bmessage
給某個(gè)方法手動(dòng)添加一個(gè)斷點(diǎn),你可能會(huì)說(shuō)驾茴,加斷點(diǎn)不用這么麻煩盼樟,我們平時(shí)加斷點(diǎn)Xcode中左側(cè)點(diǎn)擊不就OK了嗎,但是如果這個(gè)方法我們并沒(méi)有實(shí)現(xiàn)呢锈至,如下面這個(gè)例子晨缴,SecondVC
中的viewWillAppear:
病沒(méi)有實(shí)現(xiàn),現(xiàn)在輸入bmessage [SecondVC viewWillAppear:]
命令添加斷點(diǎn)裹赴,會(huì)給SecondVC父類的viewWillAppear:方法添加斷點(diǎn)喜庞,并且子類是SecondVC的時(shí)候才生效。
(lldb) bmessage [SecondVC viewWillAppear:]
Setting a breakpoint at -[UIViewController viewWillAppear:] with condition (void*)object_getClass((id)$rdi) == 0x000000010835eb80
Breakpoint 2: where = UIKit`-[UIViewController viewWillAppear:], address = 0x000000010934f899
現(xiàn)在進(jìn)入SecondVC棋返,斷點(diǎn)生效了
border&unborder
先通過(guò)help border
來(lái)看一下border的說(shuō)明和語(yǔ)法延都,功能是可以給view設(shè)置邊框顏色和寬度及其設(shè)置的層級(jí)深度,語(yǔ)法如下:
Syntax: border [--color=color] [--width=width] [--depth=depth] <viewOrLayer>
color:邊框顏色(只能是black gray red green blue cyan yellow magenta orange purple brown這幾種睛竣,否則會(huì)報(bào)錯(cuò))
width:邊框粗細(xì)
depth:層級(jí)深度(depth為0時(shí)晰房,只設(shè)置view本身,其他值則設(shè)置view及更深層級(jí)的子view)
如下例子射沟,我們給self.view及其1殊者、2層級(jí)下的子view設(shè)置紅色邊框
(lldb) border -c red -w 2 -d 2 self.view
效果是這樣的
self.view的邊框是我們?cè)O(shè)置的紅色,但是層級(jí)下的邊框顏色都是隨機(jī)的验夯,應(yīng)該是為了防止view較多且有重合的時(shí)候無(wú)法分辨區(qū)域吧猖吴。另外我們也可以通過(guò)暫停程序,輸入pview命令拿到view的地址挥转,直接操作view的地址海蔽。
相反的,unborder就是取消設(shè)置邊框绑谣,命令后只需要加view和層級(jí)深度這兩個(gè)參數(shù)即可党窜,如:(lldb) unborder self.view -d 2
參數(shù)的順序可以不分先后。
fv&fvc
fv
和fvc
這兩個(gè)命令是用來(lái)通過(guò)類名搜索當(dāng)前內(nèi)存中所存在的view和VC實(shí)例的借宵,支持正則搜索幌衣,如果正則表達(dá)式語(yǔ)法掌握很好的話,會(huì)很方便壤玫。
(lldb) fv button
0x7f8d61515900 UIButton
0x7f8d6175b820 UIButtonLabel
(lldb) fvc second
0x7f8d617699e0 SecondVC
hide&show
hide和show命令用于隱藏和顯示一個(gè)view豁护,應(yīng)用場(chǎng)景還是很常見(jiàn)的,想隱藏一個(gè)view看一下效果垦细,使用hide命令择镇,然后可以再使用show命令顯示
(lldb) hide 0x7f8d6151bfc0
(lldb) show 0x7f8d6151bfc0
mask&unmask
mask命令是為一個(gè)view添加一個(gè)覆蓋層(經(jīng)試驗(yàn),覆蓋層的顏色是隨機(jī)的)括改,目的也是為了看到某個(gè)view的布局腻豌;unmask功能相反
下面的命令就是給正方形的view和導(dǎo)航欄添加一個(gè)覆蓋層
(lldb) mask 0x7f8d6151bfc0
(lldb) mask 0x7f8d61430340
效果圖:
pcells
pcells命令可以打印層級(jí)最高的tableview當(dāng)前可見(jiàn)的所有cell,比如我在金融首頁(yè)打印嘱能,結(jié)果如下:
(lldb) pcells
<__NSArrayI 0x7fc682dc4740>(
<GMCJRMYBInfCell: 0x7fc683047a00; baseClass = UITableViewCell; frame = (0 263.094; 375 155); autoresize = W; layer = <CALayer: 0x7fc6856a67c0>>,
<GMCJXVipInfCell: 0x7fc683872a00; baseClass = UITableViewCell; frame = (0 478.094; 375 69); autoresize = W; layer = <CALayer: 0x7fc6857aaa10>>,
<GMCJXVipInfCell: 0x7fc68497aa00; baseClass = UITableViewCell; frame = (0 547.094; 375 69); autoresize = W; layer = <CALayer: 0x7fc685866680>>
)
pclass
pclass可以打印出一個(gè)對(duì)象的繼承關(guān)系吝梅,如下,打印出0x7f8d6142e0c0對(duì)象的繼承類的關(guān)系惹骂。
(lldb) pclass 0x7f8d6142e0c0
ViewController
| UIViewController
| | UIResponder
| | | NSObject
pcurl
以cur命令的形式打印NSURLRequest對(duì)象苏携,如下,初始化一個(gè)NSURLRequest對(duì)象对粪,并用pcurl打印
NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"];
request_ = [[NSURLRequest alloc] initWithURL:url];
(lldb) pcurl request_
curl -X GET --connect-timeout 60 "http://www.baidu.com"
從結(jié)果中我們可以看出該請(qǐng)求的請(qǐng)求方式是GET
右冻,超時(shí)時(shí)間是60s
装蓬,url
是http://www.baidu.com
pdata
解碼打印一個(gè)NSData對(duì)象,相當(dāng)于調(diào)用[NSString initWithData:encoding:]
纱扭,語(yǔ)法Syntax: pdata [--encoding=encoding] <data>
牍帚,命令后跟的是編碼方式,默認(rèn)是utf8乳蛾,實(shí)例如下:
_strDemo = @"今天是個(gè)好天氣";
dataDemo_ = [_strDemo dataUsingEncoding:NSUTF8StringEncoding];
(lldb) pdata dataDemo_
今天是個(gè)好天氣
pdocspath
打印應(yīng)用程序的Documents目錄路徑暗赶,語(yǔ)法是Syntax: pdocspath [--open]
,如果加了—open(-o)肃叶,相當(dāng)于open in Finder
蹂随,會(huì)在文件目錄中打開(kāi),這點(diǎn)還是比較實(shí)用的因惭。
(lldb) pdocspath -o
/Users/zhangbeibei/Library/Developer/CoreSimulator/Devices/70D5098B-52A0-441C-997E-DFB49567A80A/data/Containers/Data/Application/759F42BD-F267-4B9C-8816-3D9397EAB31C/Documents
pinternals
pinternals用來(lái)打印對(duì)象的成員變量岳锁,可以看到自定義的成員變量被打印出來(lái)了,但是系統(tǒng)自帶的屬性如view等并未打印
(lldb) pinternals self
(ViewController) $14 = {
UIViewController = {
UIResponder = {
NSObject = {
isa = ViewController
}
}
}
dicDemo_ = 0x00007fd1c371dbd0 3 key/value pairs
}
pivar
打印對(duì)象的某個(gè)成員變量蹦魔,語(yǔ)法是Syntax: pivar <object> <ivarName>
浸锨,object
是要打印的對(duì)象,ivarName
變量名稱
如下版姑,打印出當(dāng)前VC的view屬性
(lldb) pivar self _view
<UIView: 0x7fd1c3418890; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x7fd1c3418a00>>
pjson
將一個(gè)字典或數(shù)組json化并打印出來(lái),語(yǔ)法是Syntax: pjson [--plain] <object>
但是試驗(yàn)了多次都報(bào)錯(cuò)柱搜,不知道是不是有bug,后續(xù)再研究研究
visualize
這是個(gè)很有意思的功能剥险,它可以讓你使用Mac的預(yù)覽功能打開(kāi)一個(gè) UIImage, CGImageRef, UIView, 或 CALayer聪蘸。這個(gè)功能可以幫我們用來(lái)定位一個(gè)view的具體內(nèi)容,或者用來(lái)截圖表制。
我們使用該命令查看view上的按鈕健爬,如下:
(lldb) visualize 0x7fb23bf180c0
可以看到它打開(kāi)了預(yù)覽,并展示了按鈕所生成的圖片
pobjc&&poobjc
pobjc
等同于lldb
自有的p
命令
poobjc
等同于lldb
自有的po
命令
presponder
打印一個(gè)繼承于presponder的控件的響應(yīng)鏈么介,非常詳細(xì)娜遵,我打印0x7fe8d9c29200
的響應(yīng)鏈,如下:
(lldb) presponder 0x7fe8d9c29200
<UIButton: 0x7fe8d9c29200; frame = (100 220; 100 40); opaque = NO; layer = <CALayer: 0x7fe8d9c0ff50>>
| <UIView: 0x7fe8d9f04da0; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x7fe8d9f06f70>>
| | <ViewController: 0x7fe8d9c2b1c0>
| | | <UIViewControllerWrapperView: 0x7fe8d9c29c90; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x7fe8d9c19b40>>
| | | | <UINavigationTransitionView: 0x7fe8d9d0c2a0; frame = (0 0; 375 667); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x7fe8d9d11f50>>
| | | | | <UILayoutContainerView: 0x7fe8d9c2d570; frame = (0 0; 375 667); autoresize = W+H; gestureRecognizers = <NSArray: 0x7fe8d9d1f830>; layer = <CALayer: 0x7fe8d9c2d990>>
| | | | | | <UINavigationController: 0x7fe8da02fa00>
| | | | | | | <UIWindow: 0x7fe8d9c29f60; frame = (0 0; 375 667); gestureRecognizers = <NSArray: 0x7fe8d9c2ad60>; layer = <UIWindowLayer: 0x7fe8d9c298c0>>
| | | | | | | | <UIApplication: 0x7fe8d9d00ab0>
| | | | | | | | | <AppDelegate: 0x7fe8d9d10aa0>
ptv&pvc
ptv打印層級(jí)中最上面的tableview壤短,如果沒(méi)有則打印找不到的提示語(yǔ)
(lldb) ptv
<GMBTableView: 0x7f90e309c800; baseClass = UITableView; frame = (0 64; 375 554); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x7f90e5070e00>; layer = <CALayer: 0x7f90e505eee0>; contentOffset: {0, 180.5}; contentSize: {375, 1563.2064835693309}>
(lldb) ptv
Sorry, chump. I couldn't find a table-view. :'(
pvc打印當(dāng)前存在的VC的層級(jí)關(guān)系
(lldb) pvc
<UINavigationController 0x7f8d61841600>, state: appeared, view: <UILayoutContainerView 0x7f8d6142fcf0>
| <ViewController 0x7f8d6142e0c0>, state: disappeared, view: <UIView 0x7f8d61751dc0> not in the window
| <SecondVC 0x7f8d617699e0>, state: appeared, view: <UIView 0x7f8d61757340>
pviews
這個(gè)命令可以打印出當(dāng)前的view層級(jí)關(guān)系或某個(gè)指定view上的層級(jí)设拟,這個(gè)命令有助于幫助我們?cè)谡{(diào)試時(shí)定位問(wèn)題,如我們添加了一個(gè)view沒(méi)有展示久脯,可以通過(guò)這個(gè)層級(jí)關(guān)系及描述找到問(wèn)題所在纳胧。命令后不指定view默認(rèn)打印當(dāng)前存在的所有view層級(jí)關(guān)系,如下:
(lldb) pviews
<UIWindow: 0x7f81725141f0; frame = (0 0; 375 667); autoresize = W+H; gestureRecognizers = <NSArray: 0x7f8172515550>; layer = <UIWindowLayer: 0x7f8172510cf0>>
| <UIView: 0x7f8172517620; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x7f8172513830>>
| | <_UILayoutGuide: 0x7f81725189b0; frame = (0 0; 0 20); hidden = YES; layer = <CALayer: 0x7f81725024d0>>
| | <_UILayoutGuide: 0x7f81725195f0; frame = (0 667; 0 0); hidden = YES; layer = <CALayer: 0x7f817250bee0>>
| | <UIView: 0x7f817261a580; frame = (100 100; 100 100); layer = <CALayer: 0x7f8172605ff0>>
| | <UIButton: 0x7f817261abe0; frame = (100 230; 100 50); opaque = NO; layer = <CALayer: 0x7f817260fc90>>
| | | <UIButtonLabel: 0x7f81726233c0; frame = (32 14.5; 36 21.5); text = '按鈕'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7f817260cca0>>
| | | | <_UILabelContentLayer: 0x7f817241c770> (layer)
指定view則打印該view所包含的view層級(jí)帘撰,如指定當(dāng)前vc上的view:
(lldb) pviews self.view
<UIView: 0x7f8172517620; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x7f8172513830>>
| <_UILayoutGuide: 0x7f81725189b0; frame = (0 0; 0 20); hidden = YES; layer = <CALayer: 0x7f81725024d0>>
| <_UILayoutGuide: 0x7f81725195f0; frame = (0 667; 0 0); hidden = YES; layer = <CALayer: 0x7f817250bee0>>
| <UIView: 0x7f817261a580; frame = (100 100; 100 100); layer = <CALayer: 0x7f8172605ff0>>
| <UIButton: 0x7f817261abe0; frame = (100 230; 100 50); opaque = NO; layer = <CALayer: 0x7f817260fc90>>
| | <UIButtonLabel: 0x7f81726233c0; frame = (32 14.5; 36 21.5); text = '按鈕'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7f817260cca0>>
| | | <_UILabelContentLayer: 0x7f817241c770> (layer)
taplog
打印所點(diǎn)擊的控件的描述信息跑慕。先暫停程序,然后輸入taplog
命令摧找,點(diǎn)擊要打印的控件核行,然后控制臺(tái)會(huì)輸出所點(diǎn)擊控件的信息(前提是該控件的用戶交互打開(kāi)了且可以響應(yīng)點(diǎn)擊)牢硅。輸入命令后,暫停的程序會(huì)繼續(xù)運(yùn)行芝雪,這是我點(diǎn)擊一個(gè)button唤衫,輸出信息如下:
(lldb) taplog
Process 8448 resuming
<UIButton: 0x7f95d2724520; frame = (100 220; 100 40); opaque = NO; layer = <CALayer: 0x7f95d2713c40>>
注意:每輸入一次命令,只能打印一次點(diǎn)擊的信息
自定義命令
?我們也可以定義一些命令來(lái)滿足自己的需求绵脯,前提是要懂python,會(huì)的童鞋感興趣可以自己研究一下休里。
Chisel中的命令實(shí)現(xiàn)文件在/usr/local/Cellar/chisel/1.4.0/libexec/commands
路徑下蛆挫,雖然不懂語(yǔ)法,看看大致的實(shí)現(xiàn)思路還是受益匪淺的妙黍。