XCode 升級必測:Build Settings 優化等級調整快速定位 Release 版幽靈閃退問題|iOS 開發實戰技巧
iOS 開發者遇到 Release 版才出現的閃退或邏輯異常,藉由將 Debug 優化等級調整與 Release 同步,快速在本地復現問題,節省測試時間並精準定位 XCode 優化造成的 Bug,提升發佈穩定度與維護效率。
Click here to view the English version of this article, translated by OpenAI.
出於 SEO 考量,本文標題與描述經 GPT 調整,原始版本請參考內文,若有不恰當的用語,敬請指正。
[通靈筆記] XCode 升級時最好測一下的事…
遇到僅在 Build Configuration Release (正式版、線上版)才會出現的幽靈閃退或程式邏輯問題,但是 Debug 安然無恙。
Photo by Tommaso Pecchioli
TL;DR
使用新 XCode 打包發佈專案之前,除了直接 Build & Run 玩玩看有沒有跑版或異常, 請記得也試試看 :
- App Target
- 選擇
Build Settings
- 搜尋
Optimization Level
- 找到
Optimization Level
區塊 - 將
Debug
環境也設定同Release
的值 (e.g.Fastest, Smallest [-Os]
) - 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 推出後再試試看是否正常。
總結
其實不只被這個坑坑了兩次,有些已經不記得了,總之就是留個心法:
- 使用新 XCode 版本第一次打包上版時,最好測一下這個
- 問題只發生在 Release (正式版、線上版),基本上就是這個問題,可以直接改設定在本地看能不能復現
有任何問題及指教歡迎 與我聯絡 。
本文首次發表於 Medium ➡️ 前往查看,由 ZMediumToMarkdown 與 Medium-to-jekyll-starter 提供自動轉換與同步技術。