UIViewControllerのloadViewとviewDidLoadの使い分け
基本的にコードベースで(InterfaceBuilderを使わずに)構築している前提での話。。。
親view(この場合はViewControllerのview)へsubviewの追加を行う場合、
loadViewとviewDidLoadのどちらで書くべきか、書籍等でも記述が分かれているので
悩んでいたのですが、自分なりの解釈というか考え方をまとめました。
公式リファレンス(ViewControllerPGforiPhoneOS)によると、
ViewControllerのview管理は大きく
ロードサイクルとアンロードサイクルという独立した
サイクルで行われているとのこと。
ロードサイクルは
アプリからviewを要求された時にviewがまだ存在しない場合発生する。
アンロードサイクルは
アプリケーションがメモリ不足の警告を受けると発生する。
ロードサイクル:
1.viewプロパティにviewが設定されていない場合、loadViewを呼び出す。
1-1.loadViewをオーバーライドした場合
loadViewの実装中でviewプロパティにnil以外をプログラマが設定する必要がある。
1-2.loadViewをオーバーライドしない場合
ViewControllerのnibNameプロパティとnibBundleプロパティを使用して、
指定のnibファイルからビューをロードしようとする。
上記の処理でビューが見つからない場合、
ViewControllerの名前と同名のnibファイルを検索、そのファイルをロードする。
該当するnibファイルが見つからなければ、
メソッドは空のUIViewオブジェクトを作成して、viewプロパティに代入する。
2.viewDidLoadを呼び出す。(ロード時に必要な付加処理を行う。)
アンロードサイクル:
1.アプリケーションがシステムからメモリ不足の警告を受け取る。
2.ViewControllerはdidReceiveMemoryWarningを呼び出す。
ビューを解放しても安全だと判断された場合のみ、ビューが解放される。
3.ViewControllerはビューを解放するとviewDidUnLoadを呼び出す。
このメソッドをオーバーライドすることで使用していたオブジェクトを
解放する事が出来る。
リファレンスによると大きくこのような流れらしいです。
つまり、loadViewはあくまでViewControllerのviewプロパティを
間違いなくnil以外にするための処理で、
コードベースでviewを作成する場合はここでそのviewを作成する。
その他の初期化処理はviewDidLoadでするのが想定されている動き(だと思う。)
実際はloadViewとviewDidLoadは一連の流れで
呼び出されるようなのでどちらに書いても動きはする。
ただし,loadVIewをオーバーライドし、
実装中で[super loadView]もコールせず self.view 等とするとエラーになる。
(viewプロパティに値が未設定状態のため。)
ただ、アンロードサイクルを見ると、メモリが不足した際にアプリは
didReceiveMemoryWarningを呼び出し、
ビュー解放時にはviewDidUnLoadをコールする。
解放される範囲はviewDidLoadで作成したオブジェクトに限定される。
つまり、loadViewで作成したオブジェクトは範囲外となる。
長くなりましたが、この辺りを考慮すると
subviewの作成はviewDidLoadで行った方が良いという事ですかね。