Xcode Debugging 除錯技巧教學
寫程式難免會遇到 Bug。Xcode 提供了世界級的除錯工具,學會它們能讓你找 Bug 的效率提升十倍,而不是只會用 print() 大法。
這篇文章將帶你深入了解 Xcode 的除錯軍火庫。
斷點 (Breakpoints)
斷點讓程式執行到特定行數時暫停,讓你檢查當下的變數狀態。
基本操作
在程式碼行號左側點一下,會出現一個藍色箭頭,這就是斷點。拖曳它移出邊界即可刪除。
進階斷點
右鍵點擊斷點選擇 Edit Breakpoint:
- Condition (條件):例如輸入
i == 10,只有當變數i等於 10 時才會暫停。這在迴圈跑了 1000 次但只在某一次出錯時非常有用。 - Ignore (忽略):設定忽略前 N 次觸發。
- Action (動作):
- Log Message:可以在不停止程式的情況下印出訊息。例如印出
現在值是 @i@。必須勾選 "Automatically continue after evaluating actions"。 - Sound:除錯時發出聲音提示。
- Log Message:可以在不停止程式的情況下印出訊息。例如印出
全域斷點 (Exception Breakpoint) - 必學!
你是否遇過 App 閃退 (Crash),但 Xcode 直接停在 AppDelegate 或 main 函式,完全看不出是哪一行程式碼崩潰?
- 切換到左側導航列的 Breakpoint 分頁 (像標籤的圖示)。
- 點擊左下角的
+號。 - 選擇 Exception Breakpoint。
現在,當 App 下一次因為錯誤 (Exception) 而崩潰時,Xcode 會停在崩潰的那一行程式碼,而不是直接結束。這是每個 iOS 開發者開啟專案後做的第一件事。
LLDB 控制台
當程式在斷點暫停時,底下的 Console 視窗就是 LLDB (Low Level Debugger) 終端機。你可以直接輸入指令與 App 互動。
檢查變數
po 變數(Print Object):最常用。印出物件的詳細描述 (呼叫該物件的 description 屬性)。p 變數:印出變數的型別與結構。v 變數:(View) 這是較新的指令,不執行程式碼只讀取記憶體,速度比po快很多。
(lldb) po myUser.name
"Mike"
動態修改
expression 指令(簡寫e):在 Runtime 執行程式碼。
你可以在不重新編譯的情況下修改變數值,測試不同情境:
(lldb) e count = 99
(lldb) e self.view.backgroundColor = UIColor.red
執行後,記得按 "Continue" (繼續執行) 按鈕來看到效果。
呼叫堆疊
bt(Backtrace):如果你迷失了,不知道是誰呼叫了這個函式,輸入bt可以列出完整的函式呼叫堆疊。
視覺化 UI 除錯
Debug View Hierarchy (UI 階層)
在 Xcode 執行列上方有一個「三層漢堡」圖示。點擊後,Xcode 會暫停 App 並將當前的畫面「炸開」成 3D 模型。
- 用途:
- 檢查 View 為什麼沒顯示 (是被遮擋了?還是 Frame 是 0?)。
- 檢查多餘的透明 View (Ghost Views)。
- 查看 View 的詳細屬性 (Constraints, Hierarchy)。
Slow Animations (慢動作)
在模擬器 (Simulator) 的選單中:Debug > Slow Animations。 開啟後,所有動畫會變慢 10 倍。這對於檢查轉場動畫的細節、或 UI 閃爍問題非常有幫助。
記憶體除錯
Debug Memory Graph
Xcode 執行列上方的「三個圓圈連線」圖示。
- 用途:用來抓 Memory Leak (記憶體洩漏)。
- 怎麼看:左側列表如果出現紫色的驚嘆號,表示該物件能發生了 Retain Cycle (循環引用)。
- 點選該物件,右側會顯示「誰持有了它」。如果兩個物件互相指著對方,你就找到兇手了 (通常是因為 Closure 中忘記寫
[weak self])。
Instruments 效能分析
如果你的 App 跑很慢、或手機發燙,就需要用 Instruments (Product > Profile)。
- Time Profiler:最常用的工具。它會告訴你 App 的 CPU 時間都花在哪一行程式碼上。如果主執行緒 (Main Thread) 佔用過高,就會導致 UI 卡頓。
- Allocations:監控記憶體使用量,找出哪個功能吃掉了大量記憶體。
- Leaks:自動偵測未釋放的記憶體。
Sanitizers (消毒劑)
在專案設定的 Scheme (Product > Scheme > Edit Scheme) -> Run -> Diagnostics 分頁中,有幾個強大的選項:
- Address Sanitizer (ASan):偵測記憶體錯誤 (如存取已釋放的記憶體)。
- Thread Sanitizer (TSan):偵測多執行緒的 Race Condition (競爭危害)。建議在開發併發功能時開啟。
總結
- 一定要開啟 Exception Breakpoint。
- 善用 LLDB (
po,expression) 來動態除錯。 - UI 問題用 View Hierarchy,記憶體問題用 Memory Graph。
- 效能問題交給 Instruments。