[譯] Xcode 和 LLDB 高階除錯教程:第 1 部分

kirinzer發表於2019-06-20

在 2018 年的 WWDC 期間,Apple 最優秀的一些除錯工程師們開展了一場非常吸引人的會議使用Xcode和LLDB進行高階除錯。他們向我們展示了一些令人印象深刻的技巧, 關於每當發生開發人員遇到錯誤並全部修復它們時,如何利用 Xcode 的斷點和低階偵錯程式(LLDB)來優化除錯過程。

在這個 3 部分的教程中,我將向你介紹 WWDC 會議中已經完成的大部分內容。我建立了一個演示專案專門用於闡述如何配合 LLDB 使用不同型別的斷點來修復專案/應用程式中的錯誤。

演示專案

我寫了一個常見的任務專案,大多數 iOS 開發人員肯定在某些時候已經處理過。在繼續閱讀本文之前,需要首先了解它的功能或規則。以下是演示專案的全部內容:

  1. 一個表檢視控制器,在第一次開啟時載入一個文章列表。
  2. 表檢視控制器支援在到達底部時上拉載入更多文章。
  3. 限制使用者載入文章的次數 **7 次 **。
  4. 使用者可以通過下拉重新整理重新載入新文章。
  5. 導航欄上有兩個標籤,右側標籤用於顯示請求到的文章數,左側標籤則用來顯示使用者已載入文章數。

如果你比較熟悉 Objective-C,可以在下載這個專案 這裡。 更熟悉 Swift,從這裡下載 這裡。 用 Xcode 開啟並執行! ?

需要修復的錯誤!

現在你的專案準備就緒了,也許你已經注意到了下面的錯誤:

  1. 下拉重新整理沒有載入新的文章。
  2. 當使用者網路請求失敗的時候,沒有收到任何提示(例如警報控制器)。
  3. 使用者可以下拉重新整理 超過 7 次。
  4. 導航欄左側指示使用者載入次數的標籤也沒有更新。

指導原則:在本文剩下的部分,你不必停止編譯器或者重新執行應用,你可以在執行時修復這些錯誤。

表示式的力量

讓我們來解決第一個錯誤。

  1. 下拉重新整理沒有載入新的文章。

這裡有復現這個錯誤的步驟:

✦ 執行應用程式 → 前十個文章被載入。

✦ 向下滾動載入更多文章。

✦ 滾動到表檢視頂部,然後下拉重新整理。

✦ 新文章 沒有 重新載入,舊文章仍讓存在並且文章計數沒有重置。

修復此錯誤的常規方法是調查分配給表檢視控制器的專用 UIRefreshControl 的選擇器方法內部發生了什麼。前往 **PostsTableViewController** 找到有 pragma mark Refresh control support 的部分。我們能從setupRefreshControl 方法推斷出決定重新整理的是 reloadNewPosts 方法。讓我們給這個方法的第一行加一個斷點,看看這裡到底發生了什麼。現在滾動到表檢視的頂部,下拉重新整理。

Objective-C

Swift

一旦你釋放了下拉重新整理控制元件,偵錯程式就會在你設定斷點的地方暫停。現在,為了探究背後發生了什麼,點選偵錯程式的跨過按鈕。

Objective-C

Swift

現在我們就很清楚的知道發生了什麼!

因為 if 條件沒有滿足(例如isPullDownToRefreshEnabled 布林值型別的屬性被設定為 NO)因此,相應的用於載入文章的程式碼就沒有被執行。

修復這個錯誤的常規做法是停止編譯器,設定 isPullDownToRefreshEnabled 屬性為 YES/true。但是在真正的修改程式碼和停止編譯器之前,就可以對這些假設做出驗證會更方便。這裡有表示式語句的斷點偵錯程式的命令動作,非常方便。

雙擊設定的斷點,或右鍵單擊,編輯斷點並點選“新增動作”按鈕。選擇“偵錯程式命令”動作。

[譯] Xcode 和 LLDB 高階除錯教程:第 1 部分

現在我們要做的是設定 isPullDownToRefreshEnabled 屬性未 YES/true。新增如下的偵錯程式命令。

Objective-C

expression self.isPullDownToRefreshEnabled = YES
複製程式碼

[譯] Xcode 和 LLDB 高階除錯教程:第 1 部分

Swift

expression self.isPullDownToRefreshEnabled = true
複製程式碼

[譯] Xcode 和 LLDB 高階除錯教程:第 1 部分

接下來你要做的是檢查“評估動作後自動繼續”框。這會使得偵錯程式不會在每次觸發它的斷點時暫停,並在評估你剛才新增的表示式後自動繼續。

現在滑動到頂部,下拉重新整理。

新的文章被取回來了,並且替換了舊的,因此文章的技術也得到了更新。

既然你已經解決了第一個錯誤,拿起你的除蟲武器開始處理第二個吧。

  1. 當使用者的 HTTP 請求失敗的時候,沒有收到任何提示(例如警報控制器)。

這裡有復現這個錯誤的步驟:

✦ 關閉手機或模擬器的網路連線。

✦ 滑動到表檢視的頂部,下拉重新整理。

✦ 由於網路錯誤,沒有載入到新文章。

✦ 網路連線錯誤的警報控制器沒有展示給使用者。

前往 PostsTableViewController 找到 pragma mark Networking的部分。它只有一個方法 loadPosts。它利用網路管理器的單例去執行一個 GET HTTP 請求,它會返回一個包含文章物件的陣列,通過一個“成功”完成的回撥或者一個 NSError 的例項,通過一個“失敗”完成的回撥。

我們想要做的是在失敗完成處理回撥中新增一些程式碼以展示一個網路錯誤警報控制器。 如果你找到到帶有 pragma mark “Support” 的部分,你將會發現已經有一個已實現的方法 presentNetworkFailureAlertController 處理了所需警報控制器的顯示。我們需要做的就是在 loadPosts 失敗完成回撥中呼叫該方法。

常規的做法是停止編譯器,新增所需的程式碼,然後就行了。讓我們超脫出來!

這一行程式碼下,新增一個斷點

Objective-C

[self updateUIForNetworkCallEnd];
複製程式碼

Swift

self.updateUIForNetworkCallEnd()
複製程式碼

雙擊設定的斷點,點選“新增動作”按鈕。選擇偵錯程式命令動作。新增下面的偵錯程式命令。

Objective-C

expression [self presentNetworkFailureAlertController]
複製程式碼

[譯] Xcode 和 LLDB 高階除錯教程:第 1 部分

Swift

expression self.presentNetworkFailureAlertController()
複製程式碼

[譯] Xcode 和 LLDB 高階除錯教程:第 1 部分

勾選“評估動作後自動繼續”。

停用網路連線後,滾動到表檢視頂部並下拉重新整理,或者你可以向下滾動到表檢視底部嘗試載入更多。你會得到這個 ??

[譯] Xcode 和 LLDB 高階除錯教程:第 1 部分

你剛才做的是**“注入”**一行程式碼,通過一個在專用斷點內實現為偵錯程式命令動作的表示式語句。

概括

讓我簡單概括一下我們用斷點偵錯程式命令動作表示式語句做的事情:

  1. 控制存在的屬性的值。
  2. 注入新的程式碼。

這兩項任務都是在執行時實現的,我們不需要真的停止編譯器,修改內容然後重新執行應用程式。

接下來去哪裡?

檢視 第二部分 本教程中修復了額外的錯誤,並學習一種特殊型別的斷點,觀察點。

如果發現譯文存在錯誤或其他需要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可獲得相應獎勵積分。文章開頭的 本文永久連結 即為本文在 GitHub 上的 MarkDown 連結。


掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章