Post

通靈筆記 XCode 升級時最好測一下的事…

遇到僅在 Build Configuration Release (正式版、線上版)才會出現的幽靈閃退或程式邏輯問題,但是 Debug 安然無恙。

通靈筆記 XCode 升級時最好測一下的事…

ℹ️ℹ️ℹ️ Click here to view the English version of this article, translated by OpenAI.


[通靈筆記] XCode 升級時最好測一下的事…

遇到僅在 Build Configuration Release (正式版、線上版)才會出現的幽靈閃退或程式邏輯問題,但是 Debug 安然無恙。

Photo by [Tommaso Pecchioli](https://unsplash.com/@pecchio?utm_content=creditCopyText&utm_medium=referral&utm_source=unsplash){:target="_blank"}

Photo by Tommaso Pecchioli

TL;DR

使用新 XCode 打包發佈專案之前,除了直接 Build & Run 玩玩看有沒有跑版或異常, 請記得也試試看

  1. App Target
  2. 選擇 Build Settings
  3. 搜尋 Optimization Level
  4. 找到 Optimization Level 區塊
  5. Debug 環境也設定同 Release 的值 (e.g. Fastest, Smallest [-Os] )
  6. Build & Run 測看看有沒有異常

不選擇直接打包上 Testflight 測試是為了方便我們遇到問題的時候,能即時用斷點找到問題根源。

如果遇到使用者在 Release (正式版、線上版) 回報的問題(閃退或行為異常),但開發者無法在本地復現,也可以試試改這個設定在本地試試看。

可能出現的問題

  • 程式上看正確,但結果異常
  • 程式上看不會閃退的地方,卻會閃退

以上在 Debug 環境 Optimization Level = None [-O0] 都是正常的,只會出現在 Optimization Level = Fastest, Smallest [-Os] 也就是 Release 的設定值。

解法

有問題的話,問題多半跟開發者無關 ;是 XCode 優化的 Bug 導致,若一定要用這版 XCode 打包那只能先自己調整程式 Workaround,等待新版 XCode 出來再測看看是否正常。

不建議直接把 Release 改成 None,因為可能會有更多其他問題。

説故事時間

以下是這幾年工作中實際被這坑坑過的問題場景。

故事 1 — App 一直跳邀請評價 App Popup

我們的 App 之前有一個功能是打開 App 時會「邀請使用者去應用商城給評價」規則是跳三次之後就不會在跳;但是收到很多使用者回報每次開 App 都會跳,持續很久了,一直問一直問很煩。

但是我們從 Code 上看跟在本地 Build & Run 在模擬器或實機上都沒問題,也試過各種 edge case 場景都無法復現;我甚至撰寫了一個 UI Test 瘋狂重跑路徑、清除資料重試…跑了幾千次都沒遇到問題。

記得那次我苦惱到半夜三點多,萬念俱灰實在想不到是什麼問題,開始漫無目的的查看專案設定,突然靈機一動想說那把 Build Settings 都改成 Release 的值試試看好了,這才發現問題在 Optimization Level = Fastest, Smallest [-Os] 能重現,也因此才定位到出問題的位置。

Pseudocode

1
2
3
4
5
6
7
8
9
10
11
12
var invitedTimes = 0 //  Loaded from UserDefaults; will be saved back after update
func requestAppStoreReviewIfNeeded() {
  defer {
    invitedTimes += 1 // Works for now, but may have unintended side effects
  }

  guard invitedTimes < 3 else {
    return
  }
  
  self.present(AppStoreReviewRequestAlert())
}

這段程式是前人開發的,從程式上看這段程式碼雖然有 side effect,可是邏輯無問題、可以正常 Compile、在執行上之前的版本也都沒有問題。

但當我把 Optimization Level = Fastest, Smallest [-Os] 之後下斷點 Print 值就發現異常了, invitedTimes += 1 之後會直接爆炸變成 -24760045646797946 一個極大的負數,也因此使用者每次都會跳邀請評價。

當時先直接改掉這邊 defer 的寫法,就再也沒有使用者回報類似的問題了;後來回頭測試後續的 XCode 版本,相同的寫法、 Optimization Level = Fastest, Smallest [-Os] 也能正常運作了。

故事 2 — 某個頁面會直接閃退

Release (Testflight) 版在內測的時候發現有一個頁面(WebView) 只要一點擊就會閃退,可是工程師怎麼 Build & Run 在模擬器或實機上都沒問題;每每猜測一個問題點就打包一個埋 Log 或是嘗試修正的版本上 Testflight 測試,非常痛苦費時;這時又喚起我上次被支配的恐懼,立刻請同事把本地的設定改成 Optimization Level = Fastest, Smallest [-Os] 然後在 Build & Run 果然在本地復現了閃退的問題點。

主要問題是出在我們自己特化的 WebView Obj-c Code 中有一個變數在 ptimization Level = Fastest, Smallest [-Os] 時會變 null,原因不明,只能先多加判斷保護;在之前版本也都正常,只能等新的 XCode 推出後再試試看是否正常。

總結

其實不只被這個坑坑了兩次,有些已經不記得了,總之就是留個心法:

  1. 使用新 XCode 版本第一次打包上版時,最好測一下這個
  2. 問題只發生在 Release (正式版、線上版),基本上就是這個問題,可以直接改設定在本地看能不能復現

有任何問題及指教歡迎 與我聯絡


本文首次發表於 Medium ➡️ 前往查看

ZMediumToMarkdownMedium-to-jekyll-starter 提供自動轉換與同步技術。

Improve this page on Github.

Buy me a beer

74 Total Views
Last Statistics Date: 2025-04-18 | 70 Views on Medium.
This post is licensed under CC BY 4.0 by the author.