ZRealm Dev.

解決問題的道路上你並不孤單。

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

--

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

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

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 (正式版、線上版),基本上就是這個問題,可以直接改設定在本地看能不能復現

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

--

--

ZRealm Dev.
ZRealm Dev.

Published in ZRealm Dev.

解決問題的道路上你並不孤單。

ZhgChgLi
ZhgChgLi

Written by ZhgChgLi

An iOS, web, and automation developer from Taiwan 🇹🇼 who also loves sharing, traveling, and writing. https://link.zhgchg.li/

Responses (1)