XCode Build Configuration Release|Detect Ghost Crashes & Logic Bugs Before Upgrade
iOS developers facing ghost crashes or logic issues only in Release builds can identify and fix these hidden bugs before XCode upgrades, ensuring stable app performance and avoiding unexpected failures in production environments.
点击这里查看本文章简体中文版本。
點擊這裡查看本文章正體中文版本。
This post was translated with AI assistance — let me know if anything sounds off!
[Spirit Notes] Things to Test When Upgrading XCode…
Encounter ghost crashes or logic issues that only occur in the Build Configuration Release (official/online version), while Debug runs perfectly fine.
Photo by Tommaso Pecchioli
TL;DR
Before packaging and publishing a project with the new XCode, besides directly Build & Run to check for layout issues or errors, please also remember to try:
App Target
Select
Build Settings
Search for
Optimization Level
Locate the
Optimization Level
sectionSet the
Debug
environment to the same value asRelease
(e.g.Fastest, Smallest [-Os]
)Build & Run to check for any issues
Not choosing to directly upload to TestFlight for testing allows us to conveniently use breakpoints to locate the root cause of issues in real time.
If users report issues (crashes or abnormal behavior) in the Release (official, online) version, but developers cannot reproduce them locally, try changing this setting and testing it locally.
Possible Issues
The program looks correct, but the results are abnormal.
The app crashes in places where it shouldn’t crash.
The above works fine in the Debug environment with Optimization Level = None [-O0]
, but only occurs with Optimization Level = Fastest, Smallest [-Os]
, which is the Release setting.
Solution
If there are issues, they are mostly unrelated to the developer; they are caused by bugs in XCode optimization. If you must use this version of XCode for packaging, you can only adjust the code yourself as a workaround and wait for a new XCode version to see if it works properly.
It is not recommended to directly change Release to None, as it may cause more issues.
Story Time
The following are real problem scenarios I have encountered in my work over the past few years.
Story 1 — App keeps showing the rate app invitation popup
Our app previously had a feature that, when opened, would “invite users to rate the app in the store.” The rule was to show this prompt three times and then stop. However, many users reported that the prompt appears every time they open the app, lasting for a long time and becoming very annoying.
However, from the code perspective and when building & running locally on the simulator or real device, there is no problem. We have also tested various edge case scenarios but could not reproduce the issue. I even wrote a UI Test that repeatedly runs the path and clears data to retry… after thousands of runs, no issues occurred.
I remember that night I was frustrated until after 3 AM, completely at a loss and unable to figure out the problem. I started aimlessly checking the project settings when suddenly I had a flash of inspiration to try setting all the Build Settings
to Release
values. That’s when I discovered the issue was reproducible with Optimization Level = Fastest, Smallest [-Os]
, which helped me pinpoint the source of the problem.
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())
}
This code was developed by predecessors. Although it has side effects, the logic is correct, it compiles properly, and previous versions ran without issues.
But when I set Optimization Level = Fastest, Smallest [-Os]
and then put a breakpoint to print the value, I found an anomaly. After invitedTimes += 1
, it suddenly explodes into -24760045646797946
, a huge negative number. Because of this, the user is prompted to invite a review every time.
At that time, I directly changed the defer usage here, and no users reported similar issues afterward; later, when testing subsequent XCode versions, the same code with Optimization Level = Fastest, Smallest [-Os]
also worked properly.
Story 2 — A Certain Page Crashes Immediately
During internal testing of the Release (Testflight) version, we found that a page (WebView) would crash immediately upon clicking. However, the engineers had no issues when building and running on the simulator or device. Each time we suspected a problem, we packaged a version with added logs or attempted fixes and tested it on Testflight, which was very frustrating and time-consuming. This triggered my previous fear of being controlled, so I immediately asked a colleague to change the local setting to Optimization Level = Fastest, Smallest [-Os]
. After building and running, the crash issue was successfully reproduced locally.
The main issue lies in a variable within our custom WebView Obj-C code that becomes null when compiled with Optimization Level = Fastest, Smallest [-Os]
. The cause is unknown, so we can only add extra checks for protection. It worked fine in previous versions, so we will have to wait for the new XCode release to see if the problem is resolved.
Summary
Actually, I have fallen into this trap more than twice, and some instances I don’t even remember. In short, here is a mindset to keep in mind:
When packaging and submitting with the new XCode version for the first time, it’s best to test this.
The issue only occurs in Release (official, online version). Basically, this is the problem. You can directly change the settings locally to see if it can be reproduced.
If you have any questions or feedback, feel free to contact me.
This post was originally published on Medium (View original post), and automatically converted and synced by ZMediumToMarkdown.