這是本人github地址歡迎一起學(xué)習(xí)交流~
在與后臺(tái)服務(wù)器聯(lián)合調(diào)試服務(wù)接口的時(shí)候,移動(dòng)端開發(fā)人員一定遇到過一個(gè)頭疼的問題就是當(dāng)發(fā)網(wǎng)絡(luò)請求時(shí)加斷點(diǎn)調(diào)試時(shí),在Xcode的控制臺(tái)使用lldb調(diào)試器po打印返回的json數(shù)據(jù)時(shí),
顯示的還是unicode編碼格式:
如果想查看它的內(nèi)容還需要一層一層的去獲取它。然后打印,就是很麻煩。
所以我就找辦法能不能直接用命令直接把json數(shù)據(jù)里的中文直接打印顯示中文。faceBook開源了一款調(diào)試工具chisel。(簡介:Chisel擴(kuò)展了一些列的lldb的命令來幫助iOS開發(fā)者調(diào)試iOS應(yīng)用程序。)安裝它可以讓LLDB的調(diào)試更加高效。chise github地址。
安裝步驟:
1.確保終端安裝了Homebrew
Homebrew安裝教程
2.安裝好brew后,就可以執(zhí)行一下命令
brew update
brew install chisel
3.注意看Caveats下面的那兩行,意思是把第二行的文字command script import /usr/local/opt/chisel/libexec/fblldb.py添加到.lldbinit文件中,這時(shí)執(zhí)行命令echo command script import /usr/local/opt/chisel/libexec/fblldb.py >> ~/.lldbinit(粗體文字替換為你終端Caveats下面的第二行文字)可免去你去找.lldbinit文件,或者.lldbinit文件不出現(xiàn)的煩惱啊。到此步不出意外已經(jīng)安裝成功。
4.安裝成功后重新啟動(dòng)Xcode即可。
5.終端下檢查是否安裝成功輸入命令:lldb,然后輸入help,往下翻出現(xiàn)如下界面為成功
6.在控制臺(tái)使用pjson 打印json數(shù)據(jù)
7.facebook 開源的 lldb 插件 Chisel??梢宰屇愕恼{(diào)試更簡單。 chinsel還有一些其他常用的命令
7.1 pviews
這個(gè)命令可以遞歸打印所有的view,并能標(biāo)示層級,相當(dāng)于 UIView 的私有輔助方法 [view recursiveDescription] 。 善用使用這個(gè)功能會(huì)讓你在調(diào)試定位問題時(shí)省去很多麻煩。
使用示例:
(lldb) pviews view
<TestView: 0x18df8070; baseClass = UIControl; frame = (144 9; 126 167); layer = <CALayer: 0x18df8150>>
| <UIView: 0x18df81d0; frame = (0 0; 126 126); userInteractionEnabled = NO; layer = <CALayer: 0x18df8240>>
| <UIImageView: 0x18df8330; frame = (0 0; 126 126); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x18df83b0>>
| <UILabel: 0x18df8460; frame = (0 135; 126 14); text = 'haha'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x18df7fb0>>
| | <_UILabelContentLayer: 0x131a3d50> (layer)
| <UILabel: 0x18df8670; frame = (0 155; 126 12); text = 'hahaha'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x18df8730>>
| | <_UILabelContentLayer: 0x131bea10> (layer)
| <UIImageView: 0x18df88d0; frame = (0 9; 28 27); hidden = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x18df8ba0>>
7.2 visualize
這是個(gè)很有意思的功能,它可以讓你使用Mac的預(yù)覽打開一個(gè) UIImage, CGImageRef, UIView, 或 CALayer。 這個(gè)功能或許可以幫我們用來截圖、用來定位一個(gè)view的具體內(nèi)容。 但是在我試用了一下,發(fā)現(xiàn)暫時(shí)還是只能在模擬器時(shí)使用,真機(jī)還不行。
使用簡單:
(lldb) visualize imageView
fv & fvc
fv 和 fvc 這兩個(gè)命令是用來通過類名搜索當(dāng)前內(nèi)存中存在的view和viewController實(shí)例的命令,支持正則搜索。
如:
(lldb) fv scrollView
0x18d3b8c0 UIScrollView
0x137d0c50 UIScrollView
0x131b1580 UIScrollView
0x131b2070 UIScrollView
(lldb) fvc Home
0x1393fe00 HomeFeedsViewController
0x138a8e00 HomeFeedsViewController
(lldb)
7.3 show & hide
這兩個(gè)命令用來顯示和隱藏一個(gè)指定的 UIView . 你甚至不需要Continue Progress. 就可以看到效果。
7.4 mask/umask border/unborder
這兩組命令用來標(biāo)識一個(gè)view或layer的位置時(shí)用, mask用來在view上覆蓋一個(gè)半透明的矩形, border可以給view添加邊框。但是在我實(shí)際使用的過程中mask總是會(huì)報(bào)錯(cuò),估計(jì)是有bug, 那么mask/unmask 一般不要用好了,用border命令是一樣的效果,反正二者的用途都是找到一個(gè)對應(yīng)的view.
7.5 caflush
這個(gè)命令會(huì)重新渲染,即可以重新繪制界面, 相當(dāng)于執(zhí)行了 [CATransaction flush] 方法,要注意如果在動(dòng)畫過程中執(zhí)行這個(gè)命令,就直接渲染出動(dòng)畫結(jié)束的效果。
當(dāng)你想在調(diào)試界面顏色、坐標(biāo)之類的時(shí)候,可以直接在控制臺(tái)修改屬性,然后caflush就可以看到效果啦,是不是要比改代碼,然后重新build省事多了呢。
例, 其中 $122 即是目標(biāo)UIView:
(lldb) p view
(long) $122 = 140718754142192
(lldb) e (void)[$122 setBackgroundColor:[UIColor greenColor]]
(lldb) caflush
7.6 bmessage
這個(gè)命令就是用來打斷點(diǎn)用的了,雖然大家斷點(diǎn)可能都喜歡在圖形界面里面打,但是考慮一種情況:我們想在 [MyViewController viewWillAppear:] 里面打斷點(diǎn),但是 MyViewController并沒有實(shí)現(xiàn) viewWillAppear: 方法, 以往的作法可能就是在子類中實(shí)現(xiàn)下viewWillAppear:,然后打斷點(diǎn),然后rebuild。
那么幸好有了 bmessage命令。我們可以不用這樣就可以打這個(gè)效果的斷點(diǎn):
(lldb) bmessage -[MyViewController viewWillAppear:] 上面命令會(huì)在其父類的 viewWillAppear: 方法中打斷點(diǎn),并添加上了條件:[self isKindOfClass:[MyViewController class]]
7.7. 自定義命令
我們也可以自定義插件,不過前提是要懂一些 python。 比如設(shè)計(jì)一個(gè)打印keyWindow的windowLevel的命令:
創(chuàng)建python腳本文件 /magical/commands/example.py :
!/usr/bin/python
Example file with custom commands, located at /magical/commands/example.py
import lldb
import fblldbbase as fb
def lldbcommands():
return [ PrintKeyWindowLevel() ]
class PrintKeyWindowLevel(fb.FBCommand):
def name(self):
return 'pkeywinlevel'
def description(self):
return 'An incredibly contrived command that prints the window level of the key window.'
def run(self, arguments, options):
# It's a good habit to explicitly cast the type of all return
# values and arguments. LLDB can't always find them on its own.
lldb.debugger.HandleCommand('p (CGFloat)[(id)[(id)[UIApplication sharedApplication] keyWindow] windowLevel]')
其中定義了PrintKeyWindowLevel的類,需要實(shí)現(xiàn) name description run 方法來分別告訴名稱、描述、和執(zhí)行實(shí)體。
創(chuàng)建好腳本后,然后在前面安裝時(shí)創(chuàng)建的 ~/.lldbinit文件中添加一行:
script fblldb.loadCommandsInDirectory('/magical/commands/')
然后重啟Xcode之后就可以使用自定義的命令啦。
參考文獻(xiàn):
劉坤的技術(shù)博客