現象
- swift 5.2(Xcode11.4~)で、 swift compileの optimazation level:
Optimize for Size [-Osize]
だと、UILabel#textやUITextField#text セット時などにcrashするバグがある。 - Releaseビルドで設定されている可能性があるコンパイラのオプションなので、DebugビルドではCrashしないのに、ArchiveでのipaだとCrashするという状況になる
※ 下記はbugs.swift.orgから転載
crash時のログ
outlined bridged method (mbgnn) of @objc ~.text.setter
crashするコード例
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// This will crash when -Osize optimize for size
self.title = WordServer.instance.sentence
// Also crashes
//self.title = WordServer.instance.formatSentence
//ok
//self.title = WordServer.instance.ok
//also ok
//self.title = WordServer.instance.sentenceFunc()
}
}
class WordServer {
static var instance = WordServer()
var aWord: String = "test"
var anotherWord: String = "test2"
var sentence: String {
return String("Test sentence with word 1: \(aWord) and word 2: \(anotherWord)")
}
var formatSentence: String {
return String(format: "Test sentence with word 1: %@ and word 2: %@", "test1", "test2")
}
var ok: String {
return String("This one is ok.")
}
func sentenceFunc() -> String {
return String("Test sentence with word 1: \(aWord) and word 2: \(anotherWord)")
}
}
原因
- optimazation level: -Osizeのときの、swiftのコンパイルの問題らしい。
- 現在(2020/08/06)は、未解決状態。2020/6/17にpostされた問題らしい。
https://bugs.swift.org/browse/SR-13038
対策方法
現状、下記のどちらかの対策でcrash防止できた(bug報告されているので、いつかは修正されるとは思われるが)
対策方法1
- 下記のように varのプロパティ(
.sentence
)をlet
のローカル変数にしてから、UILabelやUITextFieldのtextプロパティにセットする。
//self.title = WordServer.instance.sentence
let sentence = WordServer.instance.sentence
self.title = sentence
対策方法2
- Swift Compiler - Code Generation - Optimization Level を
Optimize for Size [-Osize]
からOptimize For Speed [-O]
に変更する(通常、Archive 対象のビルトタイプ(Release)で設定) - Xcode11くらいからdefaultのOptimization Level は
Optimize For Speed [-O]
ですし、特に問題なければこちらが良さそうと思っています。