iOS Xcode調(diào)試技巧總結(jié)

關(guān)于調(diào)試的方法包括以下幾個:日志輸出&LLDB、斷點、性能、一些小技巧等幾個大的方面。我們一一進(jìn)行學(xué)習(xí)和總結(jié)。

   嘗試接受新鮮事物和方法,方法都是熟能生巧的,各種方法綜合運(yùn)用,用好了會事半功倍。

1、日志輸出&LLDB
關(guān)于日志輸出,我們最先想到的是NSLog,但是弊端在于我們需要在想要打印的位置添加NSLog代碼并重新運(yùn)行項目,這樣耽誤時間,所以我們平時用的比較多的是打斷點,然后po一下。這個“po”就是LLDB里面的一句命令。

   那么,什么是LLDB呢:它是一個有著 REPL 的特性和 C++ ,Python 插件的開源調(diào)試器。LLDB 綁定在 Xcode 內(nèi)部,存在于主窗口底部的控制臺中。調(diào)試器允許你在程序運(yùn)行的特定時暫停它,你可以查看變量的值,執(zhí)行自定的指令,并且按照你所認(rèn)為合適的步驟來操作程序的進(jìn)展。我們可以簡單的理解成它是一個調(diào)試器。

(1)LLDB命令行

   像下圖中,我們打斷點后,控制臺右邊里面會出現(xiàn)一個“l(fā)ldb”,我們平時不怎么關(guān)注它,但我們一直在使用它。
image
  <1>  **help命令**

斷點的時候,我們在控制臺右邊lldb后邊輸入一個“help”,然后敲回車,就會看到所有關(guān)于lldb的命令以及各自的介紹,如下圖:

image
image
  <2>  **print命令**

print很好理解,就是打印,使用過程中我們可以直接用p來代替print。
<3> expression命令

    該命令可以**改變程序?qū)嶋H參數(shù)的值**,目的是方便了調(diào)試:不用重新運(yùn)行項目。例如下圖中,我們簡單的做一個測試,令蘋果=1,橘子=2,all應(yīng)該=3,在斷點過程中,我們用expression命令修改了橘子的值,令橘子=5,結(jié)果再打印all的時候,all=6(親測好使)。使用過程中我們可以直接用 expr來代替expression。
image
    這里我們注意到一個“$9”,這里的9是我們使用lldb命令的次數(shù),例如下圖,我們expression一次橘子,po了一次all,再print橘子的時候,顯示的是“$11”,說明我們print命令是$10。這個不用管,只是提醒我們一下而已,作用應(yīng)該不是很大。
image
   <4> ** po命令**

現(xiàn)在我們來看看平時用的比較多的“po”,它是“print object”的簡寫。po一下,我們就可以看到對象的詳細(xì)信息。po使用的比較多,使用起來也比較簡單、方便,這里不做多余的介紹。
<5> image命令

image list 查看工程中使用的庫

image lookup --address 0x000000010e0979ac 程序崩潰的時候定位,查看具體報錯位置

   這個其實我們可以想辦法用在我們崩潰日志的收集里面,這樣的話我們就可以直接定位到崩潰信息的具體位置了。(親測,不好使。感覺xcode反饋的崩潰信息不準(zhǔn)確。)

<6> call命令

    call即調(diào)用的意思。上述的po和p也有調(diào)用的功能。所以一般只在不需要顯示輸出,或方法無返回值的時候使用call。 和上面的命令一樣,我們依然在viewDidLoad:里面設(shè)置斷點,然后在程序中斷的時候輸入下面的命令:

call [self.view setBackgroundColor:[UIColor redColor]]

    繼續(xù)運(yùn)行程序,看看view的背景顏色是不是變成紅色的了!在調(diào)試的時候靈活運(yùn)用call命令可以起到事半功倍的作用(親測好使)。

(2)LLDB調(diào)試欄

image
  一般的按鈕和功能我們用的比較多,也比較熟悉,這里我們著重介紹一下**Debug View Hierachy**和xcode8新增的**memory graph**功能。

<1>****Debug View Hierachy****

image

Debug View Hierachy,翻譯過來就是:調(diào)試視圖層次。除了點擊控制臺出的圖標(biāo),也可以從菜單中選擇Debug > View Debugging > Capture View Hierarchy 來啟動視圖調(diào)試。(我們可以看出xcode開發(fā)人員的用心之處:重疊在一起的長方形,我們大概就明白這個按鈕是表示層級關(guān)系的)在斷點或者不是斷點的情況下都可以通過點擊這個按鈕查看視圖層級關(guān)系。點擊按鈕,我們會在xcode最頂端的地方看到下圖的一個信息:

image
   capture user interface for YourAppName:capture是捕獲的意思,interface,face我們知道是臉,inter是進(jìn)入的意思,interface就是進(jìn)入臉,我們大概能夠明白這句話的意思就是“**為你的app捕獲用戶交界面**”。
image

從左到右控件排序:(上圖中也簡單解釋了各個功能)

調(diào)整視圖間距:調(diào)整不同視圖間的間距。

展示被剪切的內(nèi)容:當(dāng)前展示視圖中被剪切的部分。

展示約束:展示選中視圖的約束。

重置查看區(qū)域:將3D渲染透視圖恢復(fù)至默認(rèn)狀態(tài)。

調(diào)整查看模式:選擇性地展示3D渲染透視圖,比如僅展示內(nèi)容,僅展示框架以及同時展示內(nèi)容和框架。

縮?。嚎s小3D渲染透視圖

恢復(fù):將3D渲染透視圖恢復(fù)至默認(rèn)尺寸。

放大:放大3D渲染透視圖

調(diào)整可視視圖范圍:隱藏視圖或展示視圖,一步步解析3D渲染視圖,向左或者向右滑動滑塊兒有相反的效果。

   有了這個圖層關(guān)系,我們可以很清楚的知道頁面上邊的各個控件的位置關(guān)系,因為我們在開發(fā)階段?尤其是測試階段,某個控件上邊的字不顯示,或者控件的字被遮擋,我們可以用視圖調(diào)試器查看,是否控件是frame設(shè)置的不合理。

<2>memory graph

    **【經(jīng)驗1】**

    這個是xcode8新增的功能,翻譯過來的意思就是:**內(nèi)存圖**。有了內(nèi)存圖我們就可以解決**閉包引用循環(huán)**問題了。舉個栗子,我們寫個循環(huán)引用,如下:
image
image
image
 (說實在的,這幾個命令我在終端不知道怎么調(diào)用,試了半天,還是沒有搞出來,應(yīng)該就是內(nèi)存圖調(diào)試的樹狀結(jié)構(gòu)。如果有誰在終端里面知道怎么搞出來,煩請告訴我一下具體怎么操作,謝謝了!)所以,這里我們直接看這個**memory graph**按鈕點擊后的效果。

【經(jīng)驗2】

   說明1:這個功能是xcode8新增的功能,那么xcode7上邊肯定找不到!而xcode8還要10.11.5以上的系統(tǒng),所以,建議大家先把升級電腦系統(tǒng),然后安裝xcode8。

   說明2:  真機(jī)的話還需要iOS9或者10的系統(tǒng)。

   說明3:查找當(dāng)前默認(rèn)Xcode.app的developer路徑---終端命令行:xcode-select -p。

                如果安裝了多個版本的xcode工具,可以使用xcode-select命令指定命令行指令使用哪個版本xcode下的developer目錄下的調(diào)試工具,即修改路徑:xcode-select --switch /Applications/Xcode2.app/Contents/Developer。

  踩過的坑:

  <1>本來我用的是xcode7.2,挺好用,結(jié)果在xcode7上邊顯然沒有這個按鈕,升級到xcode8吧。

  <2>同事airdrop傳來的xcode8.0和xcode8.1,結(jié)果提示安裝不上,需要升級電腦的系統(tǒng)。

  <3>升級好了系統(tǒng),安裝好了同事airdrop傳來的xcode8.0不顯示。(!準(zhǔn)備開始抓狂  !)難道需要8.1才行?!

  <4>安裝好了同事airdrop傳來的xcode8.1,依舊不顯示。(?。?!抓狂?。。。╇y道是打開xcode時候的路徑不對?!

  <5>修改打開xcode的路徑為xcode8.1,依舊不顯示。(早已經(jīng)料到是這個結(jié)果了)難道是xcode安裝的太多了?!

  <6>卸載掉xcode7.0.1、7.2、7.3、8.0,只剩下一個8.1,依舊不顯示。(淡定的接受這個結(jié)果)難道是同事傳的xcode包有問題?!在App Store上自己下載?。?
    <7>下載好了,安裝好了,依舊不顯示。(生無可戀了。。。)

    就在此時,我不知道是被逼瘋了還是靈光一閃,拿了同事的真機(jī)運(yùn)行項目,結(jié)果居然有了memory graph按鈕!?。。?

當(dāng)你認(rèn)為最困難的時候,恰恰也就是你最接近成功的時候!

當(dāng)你放棄的時候,你永遠(yuǎn)不會知道你離成功是那么的接近!

成功很簡單,就是在你堅持不住的時候,再堅持一下!

所以建議使用memory graph功能之前確保:

升級電腦系統(tǒng)并安裝xcode8.1。(8.1比8.0更穩(wěn)定)(這里其實并不非得是App Store自己下載,別人用airdrop傳的也行)

真機(jī)iOS系統(tǒng)在9.0以上。

【經(jīng)驗3】

 在解釋上邊圖結(jié)構(gòu)和各個圖標(biāo)表示的含義之前我們先來看看這幾個**嘆號**分別代表什么。
image

紅色嘆號:這個最常見,Error=錯誤。

黃色嘆號:這個也常見,Warning=警告

紫色嘆號:這個不常見,不過使用了memory graph我們就會經(jīng)常見到,Runtime Issue=運(yùn)行時問題。

藍(lán)色箭頭:這個是檢查內(nèi)存泄露是見到的,靜態(tài)分析Command+Shift+B就可以看見。Static Analyzer Issue=靜態(tài)分析的問題。

紅色叉叉:這個實在instruments里面Leaked用法的時候見到過。UI Test Failed=UI測試失敗

在memory graph狀態(tài)下我們點擊左邊的嘆號,就會看到RunTime Issue:

image

2、斷點

斷點里面根據(jù)作用和功能也有很多種類:普通斷點、條件斷點、異常斷點、符號斷點等。我們一一學(xué)習(xí)介紹。

(1)普通斷點(不帶技能就出去闖蕩江湖的)

    當(dāng)程序運(yùn)行到斷點處時會暫停運(yùn)行。比如斷點打在11行,那么程序就會停在11行(注意:程序只運(yùn)行到了前10行,第11行其實還沒有被執(zhí)行。)。只要在代碼行旁邊點擊,就能添加一個斷點,再次點擊,斷點變成淺藍(lán)色,就能讓斷點不可用(disable了,仍然存在,只是不起作用了)。
image

(2)條件斷點(帶上技能再闖蕩江湖)

打上斷點之后,對斷點進(jìn)行編輯,設(shè)置相應(yīng)過濾條件。單擊右鍵會彈出選項框:

image

Edit BreakPoint... :編輯斷點。

Disable BreakPoint :斷點失效。(相當(dāng)于上邊說到的單擊斷點變成淺藍(lán)色,斷點失效)

Delete BreakPoint :刪除斷點。

Reveal in BreakPoint Navigator :在左邊的斷點樹狀結(jié)構(gòu)表明該斷點。

這里我們主要用到的是第一個:Edit BreakPoint。這里面設(shè)置斷點的篩選條件(雙擊斷點也可以快速進(jìn)入編輯斷點的對話框)。

image

【1】Condition:返回一個布爾值,當(dāng)布爾值為真觸發(fā)斷點,一般里面我們可以寫一個表達(dá)式。

【2】Ignore: 忽略前N次斷點,到N+1次再觸發(fā)斷點。

【3】Action: 斷點觸發(fā)事件,分為六種:

       <1>  AppleScript:執(zhí)行腳本。

       <2>  Capture GPU Frame:用于OpenGL ES調(diào)試,捕獲斷點處GPU當(dāng)前繪制幀。 

       <3>  Debugger Command:和控制臺中輸入LLDB調(diào)試命令一致。

       <4>  Log Message:輸出自定義格式信息至控制臺。

       <5>  Shell Command:接收命令文件及相應(yīng)參數(shù)列表,Shell Command是異步執(zhí)行的,只有勾選“Wait until done”才會等待Shell命令執(zhí)行完在執(zhí)行調(diào)試。

        <6>  Sound:斷點觸發(fā)時播放聲音。

【4】Options(Automatically continue after evaluating actions選項):選中后,表示斷點不會終止程序的運(yùn)行。

【1】Condition:這里我設(shè)置i==6,我們看LLDB控制臺打印結(jié)果:

image

這里打印了0-5,然后斷點斷了。這樣做的目的就是我們不用在循環(huán)里面一個一個的點擊下一步,直接跳至我們想要看到的那一步。

【2】Ignore:這里我把Condition的條件取消,設(shè)置Ignor的條件為3,我們看LLDB控制臺打印結(jié)果:

image

結(jié)果是將0-2的循環(huán)直接忽略,而后邊的循環(huán)依舊每次在斷點的位置斷一次。

(3) 異常斷點 Exception Breakpoint(全局?jǐn)帱c)

  異常斷點可以快速定位不滿足特定條件的異常,比如常見的數(shù)組越界,這時候很難通過異常信息定位到錯誤所在位置。這個時候異常斷點就可以發(fā)揮作用了。

 添加異常斷點:
image
    同樣的,全局?jǐn)帱c也是可以編輯的,單擊右鍵或者雙擊斷點就會彈出編輯框,編輯的項目和上述是一樣的。

(4)符號斷點 Symbolic Breakpoint

    符號斷點的創(chuàng)建也同異常斷點。一般符號斷點可以在你指定的[類名 方法名]時中斷執(zhí)行**。** 
image

3、性能檢測:

(1)靜態(tài)分析:通過對代碼靜態(tài)分析,找出代碼潛在的錯誤,如內(nèi)存泄漏、空引用、未使用函數(shù)等。

            方法:菜單“Product"->"Analyze"或者Shift+Command+B,然后想辦法**消滅藍(lán)箭頭**。

(2)動態(tài)分析:通過Instruments工具跟蹤分析程序運(yùn)行時的數(shù)據(jù)

            方法:參考《[Instruments性能檢測](http://www.itdecent.cn/p/9e94e42cfb01)》

4、其他小技巧

   (1)**模擬器調(diào)試:FPS**

    在《[Instruments性能檢測](http://www.itdecent.cn/p/9e94e42cfb01)》一文中我們就介紹了**FPS=Frame Per Sencond:?一秒鐘渲染多少幀**。

    根據(jù)蘋果全球開發(fā)者大會WWDC的說法,**當(dāng)FPS低于45時,用戶就會察覺滑動有卡頓。**

    編譯并運(yùn)行應(yīng)用程序,選中模擬器,從 Debug菜單中選擇Color Blended Layers選項。
image
image

紅色:表示這些layer是透明的,系統(tǒng)在渲染這些像素點的時候,需要將該view及view一下的其他view混合之后才能得到實際的顏色。紅色越深,表明系統(tǒng)在渲染的時候越費(fèi)勁。

綠色:表示這些layer是不透明的,易于渲染。

黃色:表示這里的點無法直接繪制在屏幕上,此時系統(tǒng)需要對相鄰的像素點做反鋸齒計算,增加了圖形負(fù)擔(dān)。產(chǎn)生的原因是這個控件的背景是通過圖片拉伸得到的。

所以推薦盡可能地使用不透明的圖層。

  **(2) 真機(jī)調(diào)試:截圖。**

   當(dāng)我們在模擬器上邊運(yùn)行項目的時候,想要給產(chǎn)品或者測試人員看一下頁面效果如何,qq截圖就可以了,如果在真機(jī)上呢怎么截圖呢?一般我們會拿著真機(jī)給產(chǎn)品或者測試人員看看,但是如果來回折騰很麻煩,我們也可以用自己的手機(jī)照相然后發(fā)圖片給他們,這里還有一個更好的辦法對真機(jī)進(jìn)行截圖:運(yùn)行項目,**選擇Debug--View Debugging--Take Screenshot of 真機(jī)名字**,這樣在你的電腦桌面上邊就會有一張你的真機(jī)上邊選好頁面的截圖。
image

參考來源
http://www.itdecent.cn/p/124699399a45

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容