Xcode自帶的超好用的診斷工具

知識小集發表於2018-05-09

歡迎關注我們的公眾號,我們每週都會有原創文章分享。我們主要定位在移動開發領域,分享移動開發技術,包括 iOS、Android、小程式、移動前端、React Native、weex 等。

知識小集 GitHub

Xcode自帶的超好用的診斷工具

“我靠,這個問題怎麼查,嘗試了幾十遍了,都不能復現?”,“我去,這個問題讓我匪夷所思啊”……經常聽到這類的聲音,所以今天打算給大家簡單介紹幾款 Xcode 自帶的超好用的診斷工具,來提高大家的工作效率。(本文不會介紹詳細的使用方法,請自行谷歌或者百度。)

善待編譯警告

Xcode 已經為我們準備了十分豐富的編譯警告,儘管這些警告不會導致編譯不過,但是背後一定沒有無緣無故的恨。請正確對待所有警告,避免在執行時產生一些讓你感到難以捉摸的現象,Treat Warnings as Errors也不失為一個不錯的選擇。如果你對某些警告有絕對的自信,可以通過修改 Build Settings 裡的 Warnings 選項,或者在提示警告的程式碼處新增 diagnostic ignore 來消除它們。隨著 Xcode 的不斷更新,你還應該通過工程檔案的 Editor-Validate Settings 來將工程配置選項改為最優。

不要忽視Analyze

很早以前 Xcode 就已經為我們提供了靜態檢測工具,用它可以檢測一系列難以發現的問題,例如記憶體洩露、邏輯錯誤、未使用的變數和未包含的庫等。對於很多專案而言,完整的跑一次 Analyze 會花費較長的時間,也許是因為這一點,這項工具被越來越多的開發者忽視掉。你可以通過修改 Build Settings 裡的 Analyze During 'Build' 在平時開發除錯的過程中即時地進行Analyze。

執行時診斷

除了編譯警告和 Analyze,蘋果還為我們提供了更多的動態除錯工具。它們分散在 Xcode 的各個角落,與我們日常開發息息相關,潤物細無聲。

Debug Gauges

Xcode自帶的超好用的診斷工具

App 開始除錯之後,Xcode 左側的 navigator 檢視會自動切換到 debug navigator。在這裡,預設情況下會展示幾項關鍵指標來為你概述當前 App 的執行狀態。通過它們你可以大致瞭解每個執行緒的執行、記憶體申請、電量使用、磁碟讀寫、網路操作等狀況。如果你關心更詳細的診斷資訊,你可以很方便地進入 Instruments 進行相應的診斷。

###Process Debug

Xcode自帶的超好用的診斷工具

Xcode 為我們提供了四種程式除錯:

  • View Process by Thread:執行緒的呼叫棧,這個是預設的,也是我們最常用的。加個斷點,檢視當前的所有執行緒呼叫情況。

  • View Process by Queue:和 View Process by Thread 差不多,當前佇列名稱會替代 Thread 命名,同時顏色也要豐富一些。

  • View UI Hierarchy:可以切換到上帝視角來檢視檢視層級和各檢視屬性。

  • View Memory Graph Hierarchy:可以方便的檢測迴圈引用等記憶體洩露問題,非常實用。

開啟Diagnostics

Xcode自帶的超好用的診斷工具

除了 Xcode 在早期為我們提供的 Guard MallocZombie Objects 等,在最近兩個版本中先後引入的 SanitizersMain Thread Checker 進一步完善了開發過程中的檢測工具。

  • Address Sanitizer

對於 MRC 環境下的 OC 來講,在一個物件被釋放之後再去對它進行操作會觸發 crash;進入 ARC 時代之後,我們越來越少地去關心這個問題。但當你使用 Core Foundation,或者混編 C\C++ 的時候,這個問題會表現得不可預料。當一片記憶體區域被釋放之後,在該區域被重新分配之前去訪問它不會出現問題,這就帶來了很大的隨機性。除此之外,如果你在使用指標訪問記憶體的時候不小心越了界,帶來的後果也是不可預料的。對於這些問題,Xcode 提供了 Address Sanitizer 來更有力地進行檢測。

  • Thread Sanitizer

以往,Data Race 的問題是十分難定位和排查的,因為它帶來的問題往往是不可預期的。Xcode 通過記錄每次記憶體訪問的時間等資訊,在每次訪問記憶體的時候進行檢測。在日常開發除錯過程中你可以選擇性地開啟這項工具,但是在單元測試中,應當考慮開啟它,若你的用例覆蓋度較高,它可能可以為你發現絕大部分多執行緒資料競爭的問題。

  • Undefined Behavior Santizer

未定義行文檢測,比如說除以 0,載入記憶體對其指標、非關聯一個空指標等。有可能引發 crash 也可能不 crash,具體情況和編譯器有關係,但是我們應該避免這種事情的發生。

  • Main Thread Checker

檢測在子執行緒使用 AppKitUIKit 和其他 API,這個檢測工具是預設開啟的,開啟後不需要重新編譯。原理是通過App啟動後,自動替換隻能在主執行緒使用的API,當呼叫此類API時剖出異常。

值得一提的是,由於 Address SanitizerGuard MallocZombie Objects 的實現原理直接或間接地影響了執行時物件的記憶體管理,若開啟了這些診斷工具,Debug Gauges 中的 Memory 一項會失效。

總結

儘早的解決警告和診斷 App 會大大提升上線後 App 的穩定性,同時也可以提高我們的工作效率,那還等什麼呢,快點行動起來吧。

相關文章