先日、Xcode10.3でビルドしていたプロジェクトをXcode11.3にアップデートしてiOSアプリを更新しました。
更新内容は以下の通りです。
1. Xcodeのバージョンアップ
2. Swiftバージョンアップ(3.3 -> 5.0)
3. 使っているOSSのアップデート(cocoapods)
4. 対応OSバージョンアップ(iOS10〜サポート -> iOS11〜サポート)
各OSでのテスト、複数端末でのテストを行って問題なかったのでリリースしたのですが、一部の端末でアプリが起動しなくなる事がわかりました。
クラッシュログや、TestFlightでのテストの結果、一番初めに表示しているViewのviewDidLoadメソッドでself.navigationControllerがnilである事がわかりました。
現象が発生する端末やOSバージョンには傾向が見られませんが、NGな端末はアプリを再インストールしたり、OSを再起動しても状況は変わりませんでした。
### 問題のコード
```objc
`gutter:true;
let height = self.navigationController?.navigationBar.frame.size.height
xxx.size.height = height! // これがダメ
```
そもそも、Optionalな値を!で強制的に使用しているのがNGなのですが、今までここでクラッシュした事はありませんでした。
この部分がCallされるのは、AppDelegateのdidFinishLaunchingWithOptionsでViewControllerを初期化して、NavigationConteollerに設定、windowに設定した後のはずです。
そこで、AppDelegateを確認すると以下のようになっていました。
```objc
`gutter:true;
:
let vc = ViewController()
let nv = NavigationController(rootViewController: vc)
window.rootViewController = nv
:
```
想像通り、window.rootViewControllerにNavigationControllerを設定した中でViewControllerのviewDidLoadがCallされていました。
しかしながら、viewDidLoadでnavigationControllerがnilになっています😱
調べてみると、端末によって、window.rootViewControllerに設定したら同じスレッドでそのままviewDidLoadがCallされる場合と、少ししてからCallされる場合の2パターンがあるようです。
なので、viewDidLoadの中で、初期化されている事が前提のコードがあると、それもこけます🧐
## 明日の為に
1. オプショナル型を!で強制展開する時には、必ず成功する確証がある時のみにする
2. アプリで使っているデータを初期化する場合は一番初めに行う(viewなどをinitする前)
当たり前の事ですが、今一度確認したいです。
0 件のコメント :
コメントを投稿