歡迎關注我們的公眾號,我們每週都會有原創文章分享。我們主要定位在移動開發領域,分享移動開發技術,包括 iOS、Android、小程式、移動前端、React Native、weex 等。
“我靠,這個問題怎麼查,嘗試了幾十遍了,都不能復現?”,“我去,這個問題讓我匪夷所思啊”……經常聽到這類的聲音,所以今天打算給大家簡單介紹幾款 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
當 App
開始除錯之後,Xcode
左側的 navigator
檢視會自動切換到 debug navigator
。在這裡,預設情況下會展示幾項關鍵指標來為你概述當前 App
的執行狀態。通過它們你可以大致瞭解每個執行緒的執行、記憶體申請、電量使用、磁碟讀寫、網路操作等狀況。如果你關心更詳細的診斷資訊,你可以很方便地進入 Instruments
進行相應的診斷。
###Process Debug
Xcode
為我們提供了四種程式除錯:
-
View Process by Thread
:執行緒的呼叫棧,這個是預設的,也是我們最常用的。加個斷點,檢視當前的所有執行緒呼叫情況。 -
View Process by Queue
:和View Process by Thread
差不多,當前佇列名稱會替代Thread
命名,同時顏色也要豐富一些。 -
View UI Hierarchy
:可以切換到上帝視角來檢視檢視層級和各檢視屬性。 -
View Memory Graph Hierarchy
:可以方便的檢測迴圈引用等記憶體洩露問題,非常實用。
開啟Diagnostics
除了 Xcode
在早期為我們提供的 Guard Malloc
、Zombie Objects
等,在最近兩個版本中先後引入的 Sanitizers
和 Main 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
檢測在子執行緒使用 AppKit
,UIKit
和其他 API
,這個檢測工具是預設開啟的,開啟後不需要重新編譯。原理是通過App啟動後,自動替換隻能在主執行緒使用的API,當呼叫此類API時剖出異常。
值得一提的是,由於 Address Sanitizer
、 Guard Malloc
或 Zombie Objects
的實現原理直接或間接地影響了執行時物件的記憶體管理,若開啟了這些診斷工具,Debug Gauges
中的 Memory
一項會失效。
總結
儘早的解決警告和診斷 App
會大大提升上線後 App
的穩定性,同時也可以提高我們的工作效率,那還等什麼呢,快點行動起來吧。