viewWillDisappear: では super をいつ呼ぶべきか
- (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; // some implements }
と
- (void)viewWillDisappear:(BOOL)animated { // some implements [super viewWillDisappear:animated]; }
どちらが良いの?という議題
Appleのドキュメント
Subclasses can override this method and use it to commit editing changes, resign the first responder status of the view, or perform other relevant tasks. For example, you might use this method to revert changes to the orientation or style of the status bar that were made in the viewDidDisappear: method when the view was first presented. If you override this method, you must call super at some point in your implementation.
最後の1文にメソッドをオーバーライドする場合は実装のどこか (at some point) で super を呼ばなければならないとの記述がある。
呼ぶべきタイミングについては自由という様にも解釈できる。
クラスヘッダ
- (void)viewWillDisappear:(BOOL)animated; // Called when the view is dismissed, covered or otherwise hidden. Default does nothing
デフォルトでは何もしないという記述がある。
何もしないのであれば [super viewWillDisappear:animated];
はどこで呼んでも影響が無い、むしろ呼んでも呼ばなくても同じとも言える。
Appleのサンプルコード
iOS Dev Center で viewWillDisappear:
で検索して Sample Code タブを選択
https://developer.apple.com/search/?q=viewWillDisappear&type=Sample%20Code
検索にかかったサンプルコードを確認
大抵が最初に super を呼ぶパターンで、一部は super を最後に呼ぶパターンになっている。
AVPlayerDemo については ViewController によってそれぞれ異なる形で super が呼ばれているため両方が YES になっている。
super を呼んでいなかったり、super を呼んでいるだけで前後に実装の無いものはハイフンで記載している。
それぞれのパターンで viewWillDisappear:
でどのような処理を行っているかをまとめた。
最初に呼んでいるパターン
- resignFirstResponder
- delegate を nil に設定する
- completionHander を nil に設定する
- NSNotificationCenter の通知解除
- KVO の通知解除
- UIToolBar の状態変更
- statusBar の状態変更
- ゲームループの停止
- UIControl の enabled の状態変更
- フラグのリセット
- AVPlayer の再生停止 (AVCustomEdit, AVTimedAnnotationWriter, AVCompositionDebugVieweriOS)
- CLLocationManager の位置情報更新停止
- UIActivityIndicator の停止
- networkActivityIndicatorVisible を停止
- CADisplayLink の停止
最後に呼んでいるパターン
- AVPlayer の再生停止 (AVPlayerDemo, SloPoke)
- CBCentralManager のスキャン停止
- CBPeripheralManager のアドバタイズ停止
- NSNotificationCenter の通知解除 (PhotosByLocation)
- delegate を nil に設定する (PhotosByLocation)
- UINavigationBar の状態変更 (SloPoke)
- UIApplication リモートコントロールイベントの受け取り停止
PhotosByLocation を除いては NSNotificationCenter と KVO の通知解除、delegate への nil の設定は super を呼んだ後に行っている。
AVPlayer の停止は半々ぐらいのケースに分かれる。
いつ呼ぶべきか
呼ぶ「べき」タイミングはないと思う。各々の実装で良いかと。
viewWillAppear:
で何らかの tear down 系の処理を行っていてその ViewController をサブクラス化して使うケースで、サブクラスによる追加の tear down 系の処理と super との処理の順番が重要な場合には super を呼ぶタイミングは意識する必要が出てくる。
通常の UIViewController のサブクラスにおいて通知解除、画面表示の更新停止、継続的なデータフェッチの更新停止などのみを行う場合にはタイミングは気にしなくても良い。
チーム作業での混乱を防ぐためにコーディングガイドラインで、基本的にはいつ super を呼ぶようにするか、どのようなケースで基本から外れるのか認識を合わせておくのも良いと思う。