iOS 調試技能 - bug定位、性能調試濒生、常見問題分析

1. 常用調試方式

Print VS 單步調試

說到調試埋泵,剛入門編程時,用得最多的無疑是 print,畢竟連教材都是這樣寫的丽声,直接打印礁蔗,簡單明了。但是當打印內容太多時雁社,就容易看得頭暈腦脹了浴井,這里以 Swift 為例,稍微改進下 print 方法:

/**
print log
#file       String    包含這個符號的文件的路徑
#line       Int       符號出現(xiàn)處的行號
#column     Int       符號出現(xiàn)處的列
#function   String    包含這個符號的方法名字
*/
func printLog<T>(_ message: T,
                    file: String = #file,
                    method: String = #function,
                    line: Int = #line)
{
    #if DEBUG
    print("\((file as NSString).lastPathComponent)[\(line)], \(method): \(message)")
    #endif
}

打印的時候輸入文件的路徑霉撵,行列號和方法明等磺浙,這樣更方便通過 print 的日志來精準定位問題。但是通過 print 來調試時徒坡,有時候就不容易發(fā)現(xiàn)一些邏輯上的問題撕氧,或者需要使用大量的 print 輸出日志,這個時候就可以考慮使用單步調試:

ADD2B91E-EA8A-4C0B-976A-9E9BE78C27E9.png

單步調試的時候可以逐步查看代碼的執(zhí)行過程喇完,是解決 bug 的神器伦泥,如果你是一位新手,這肯定是你首要學會的技能锦溪,在單步調試的時候不脯,一般都會結合 LLDB 命令來使用,關于 LLDB 的內容下面會詳細說刻诊。

但在實際開發(fā)中防楷,有些場景是無法通過單步調試來復現(xiàn)的,比如說多線程的場景下则涯,在使用單步時复局,很多時候是無法復現(xiàn)真實場景的,這個時候就需要使用萬能的 print 了是整⌒ごВ總之,兩種方式是必不可少的浮入,在實際開發(fā)中龙优,很多時候我們不會直接使用 print,一般都會使用日志框架事秀,來對日志進行和記錄和收集彤断。

Crash Report

在我們平常的開發(fā)中,你提交測試包給 QA 測試時易迹,他那邊出現(xiàn)在了 crash宰衙,但卻不是調試模式下,這里我們就可以通過通過測試設備睹欲,在 Xcode 的 Devices 中把 crash 日志導出來:

5786A795-FC55-4A6F-8C3D-8CFE014257CC.png

關于如何去閱讀 Crash report 和定位該 Crash 原因供炼,可以看我之前寫的文章:淺談 Crash Report一屋,這里就不再重復談。

dSYM 文件

首先來科普下什么是 dSYM 文件:

Xcode編譯項目后袋哼,我們會看到一個同名的 dSYM 文件冀墨,dSYM 是保存函數(shù)地址映射信息的文件,調試的 symbols 都會包含在這個文件中涛贯,并且每次編譯項目的時候都會生成一個新的 dSYM 文件诽嘉。

應用上架后,可以通過類似友盟統(tǒng)計等工具收集線上的 Crash弟翘,這里直接以友盟的為例虫腋,先看下 Crash 信息:

601D48A0-954A-4A0B-9AE3-252E7C966999.png

這里可以看出這個錯誤的原因是數(shù)組越界了,那么問題來了稀余,我們并不知道是哪里越界悦冀,上面只給出了一個內容地址:

5   YHRSS                        0x1000420b0 YHRSS + 270512
6   YHRSS                        0x100041378 YHRSS + 267128

這時就可以通過 dSYM 文件來定位出問題的地方了。首先通過 archives 來找到 dSYM 文件:

步驟1:


步驟1.png

步驟2:


步驟2.png

步驟3:


步驟3.png

我們 cd 到該文件目錄下睛琳,然后執(zhí)行:

atos -arch arm64 -o YHRSS 0x1000420b0

注意這里的 -arch 是和上面 crash 報告中的對應雏门,否則是看不到相應的信息的:

$ atos -arch arm64 -o YHRSS 0x1000420b0
specialized YHArticlesViewController.tableView(_:heightForRowAt:) (in YHRSS) (YHArticlesViewController.swift:215)

這樣我們能就精準地獲取 crash 出現(xiàn)的具體位置,然后就該是發(fā)揮自我價值的時候了掸掏。

那些項目中遇到的常見問題定位

循環(huán)引用快速定位和解決

如果你懷疑存在循環(huán)引用,你可以 Instrument 工具來定位宙帝,但這也太麻煩了丧凤,你可以直接在 deinit{} 方法( OC 中對應的就是 dealloc 方法)里面打一個斷點,如果頁面退出時沒有執(zhí)行到該處步脓,就說明該頁面存在循環(huán)引用愿待,頁面內存沒有辦法釋放。

如果存在循環(huán)引用靴患,那么首先要檢查的是 block 里面的 self 是不是需要 weak仍侥,自定義的 delegate 是不是寫成了 strong,絕大部分都是這兩個原因導致的鸳君,逐個去檢查就好农渊。

2. LLDB 常用命令的使用

什么是 LLDB

LLDB 是 Xcode 內置的調試工具,它與 LLVM 編譯器一起或颊,給開發(fā)者提供更豐富的流程控制和數(shù)據(jù)檢測的調試功能砸紊,它的主要功能是為 Xcode 提供底層調試環(huán)境。

常用命令

  1. help 最牛逼的命令
    help 可以輸出 LLDB 的命令囱挑,使用 help <command> 可以輸出相應命令的 help醉顽。

    圖片.png
  1. po、p 打印值

    圖片.png

    po 和 p 的區(qū)別在于使用po只會輸出對應的值平挑,p 則會返回值的類型以及命令結果的引用名游添。

  2. exp 輸出或修改值(主要作用是修改值)

    圖片.png
  3. bt 當前線程的調用堆棧系草,可能通過后面添加數(shù)字來限制輸出線程數(shù),如 bt 5唆涝,只輸出前5個找都。

    52245C67-3376-4A95-A323-A3875BEBF2F9.png
  4. thread return 跳出當前方法的執(zhí)行(thread return 0 設置返回值),但在 swift 中石抡,是無法使用的准谚,已知的問題了中狂,只能等待修復吧,這里給個 OC 的例子:

    51084CDC-031A-490C-A0BE-474DA5C6B423.png

3. Instrument 的使用

寫在最前面,在做性能測試的時候德绿,不能用模擬器,用真機起胰,用真機升酣,用真機,重要的事情說三次煞茫。

Time Profiler

time profile 是時間分析工具帕涌,主要用來檢測應用 CPU 的使用情況,可以看到應用程序中各個方法消耗 CPU 時間续徽。關于概念蚓曼,這里就不詳細介紹了,直接進行實際操作:

  1. 通過 xcode 中的 product --> profile 來啟動 Instrument钦扭,并選擇 Time Profiler 工具:

    BAE9B1B4-19D3-447D-9D59-42955BC22114.png
  2. 運行 Time Profiler纫版,配置顯示方式,分線程顯示和隱藏系統(tǒng)的無關內容:

    B6CA42E2-0AEC-4787-AA39-C1B48FD7CF1F.png
  3. 在手機上執(zhí)行想要測試的操作客情,執(zhí)行完后停止 Time Profiler 進行分析:

    CBE4F6B3-6DD8-4CC0-8280-8F15A599B425.png
  4. 找到主要耗時的地方其弊,并定位到具體的代碼行(點擊方法的小箭頭就可以進入相應的代碼處):

    11C6F965-91F3-4A44-ACF8-1F2FC03F2DC3.png

    這里可以看出,主要有兩一個耗時的操作膀斋,但明顯后面那我格式轉換我們沒有辦法去處理梭伐,我們只能從第一個入手。它每次創(chuàng)建都比較耗時仰担,那么我們就不要多次去創(chuàng)建糊识,因為它每次使用的格式的都是一樣的,這樣我們實質上只需要創(chuàng)建一次就可以了惰匙。那我們有什么方法去只創(chuàng)建一次呢技掏,首先能想到的肯定是單例,但是用單例太麻煩了项鬼,通過 static 定義成一個常量就可以了哑梳,就這樣,這處的性能問題就解決了绘盟,其它地方也可以通過同樣的方法鸠真,逐步分析和解決就可以了悯仙。

Leaks

使用的步驟幾乎和上面的一樣,這里就不重復上圖了吠卷,但在出現(xiàn)內存泄露的地方锡垄,我們需要手動去選取對應的位置,這樣才方便分析問題:

3404A8AC-066D-4800-89BE-9DB013D2B2B0.png

因為 Leaks 的使用和 Time Profiler 是一樣的祭隔,這里就不去重復描述使用過程货岭,在這里簡單地介紹下會出現(xiàn)內存泄露的常見情況:

  1. 循環(huán)引用
  2. ARC 中使用 C 方式開辟的內存沒有手動釋放
  3. URLSession 對象的多次創(chuàng)建,使用 AFNetworking 時也是同理

這里單獨針對 URLSession 對象的多次創(chuàng)建會導致內存泄露問題單獨說明下疾渴,其實我們只要看過 URLSession 的文檔我們就知道了:

Important

The session object keeps a strong reference to the delegate until your app exits or explicitly invalidates the session. If you don’t invalidate the session, your app leaks memory until it exits.

session 對象會一直持有強引用千贯,導致無法釋放,多次創(chuàng)建就會有內存泄露問題搞坝,關于 session 的使用搔谴,我們應該使用一個單例來管理。而且唯一的 session 還可以加快網絡請求桩撮,如連接復用等敦第,這里就不詳細說,回頭有時間再單獨寫一篇相關的文章店量,畢竟這不是一兩句話就能說清楚的事情芜果。

參考文獻

  1. 與調試器共舞 - LLDB 的華爾茲
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市融师,隨后出現(xiàn)的幾起案子师幕,更是在濱河造成了極大的恐慌,老刑警劉巖诬滩,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異灭将,居然都是意外死亡疼鸟,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進店門庙曙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來空镜,“玉大人,你說我怎么就攤上這事捌朴∥庠埽” “怎么了?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵砂蔽,是天一觀的道長洼怔。 經常有香客問我,道長左驾,這世上最難降的妖魔是什么镣隶? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任极谊,我火速辦了婚禮,結果婚禮上安岂,老公的妹妹穿的比我還像新娘轻猖。我一直安慰自己,他們只是感情好域那,可當我...
    茶點故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布咙边。 她就那樣靜靜地躺著,像睡著了一般次员。 火紅的嫁衣襯著肌膚如雪败许。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天翠肘,我揣著相機與錄音檐束,去河邊找鬼。 笑死束倍,一個胖子當著我的面吹牛被丧,可吹牛的內容都是我干的。 我是一名探鬼主播绪妹,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼甥桂,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了邮旷?” 一聲冷哼從身側響起黄选,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎婶肩,沒想到半個月后办陷,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡律歼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年民镜,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片险毁。...
    茶點故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡制圈,死狀恐怖,靈堂內的尸體忽然破棺而出畔况,到底是詐尸還是另有隱情鲸鹦,我是刑警寧澤,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布跷跪,位于F島的核電站馋嗜,受9級特大地震影響,放射性物質發(fā)生泄漏吵瞻。R本人自食惡果不足惜嵌戈,卻給世界環(huán)境...
    茶點故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一覆积、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧熟呛,春花似錦宽档、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至九府,卻和暖如春椎瘟,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背侄旬。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工肺蔚, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人儡羔。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓宣羊,卻偏偏與公主長得像,于是被迫代替她去往敵國和親汰蜘。 傳聞我的和親對象是個殘疾皇子仇冯,可洞房花燭夜當晚...
    茶點故事閱讀 43,697評論 2 351

推薦閱讀更多精彩內容