ProgrammingiOSエンジニア

UIKitにおけるビューコントローラーのライフサイクルについて説明し、ライフサイクルに対する不適切な操作がメモリリークやUIのバグにつながる可能性がある理由、その際に知っておくべき注意点は何ですか?

Hintsage AIアシスタントで面接を突破

回答

UIViewControllerのライフサイクルには、以下の重要なメソッドが含まれます:

  • init(nibName:bundle:) / init(coder:): 初期化
  • loadView: ビューの階層を作成
  • viewDidLoad: ビューがロードされた(初期設定に最適な場所)
  • viewWillAppear / viewDidAppear: ビューが表示される/表示された
  • viewWillDisappear / viewDidDisappear: ビューが非表示になる/非表示になった
  • deinit: コントローラーの削除

メソッドの呼び出し順序:

  • 最初にビューの階層が作成される(loadView の後に viewDidLoad
  • 画面に表示または非表示になるたびに viewWillAppear/viewWillDisappear が呼び出され、その後 viewDidAppear/viewDidDisappear が呼び出される
  • 削除後に deinit

注意点:

  • viewDidLoad ではビューのサイズにアクセスしない方が良い — 不正確な場合があるため
  • リソース(オブザーバー、タイマー)を deinit または viewWillDisappear で解放することが重要
  • サブビューの追加は viewDidLoad で行い、viewWillAppear では行わないこと — 各表示時に重複する可能性があるため

例:

class MyViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() setupViews() setupBindings() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // 通知に登録 } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) // 通知から登録解除 } deinit { // クリーンアップ } }

問題のある質問

質問:

ビューコントローラーはライフサイクルの外でビューのプロパティにアクセスしても良いですか(例えば、初期化子内で)?

回答: いいえ、loadView が呼び出される(またはオーバーライドされる)前は、ビューに関連するすべてのプロパティが初期化されていない可能性があります。loadView/viewDidLoad の外でのアクセスはクラッシュを引き起こします。

例:

// エラー: self.view はまだ初期化されていません! init() { super.init(nibName: nil, bundle: nil) self.view.backgroundColor = .red //クラッシュ }

このテーマの注意点を知らないための実際のエラーの例


物語

プロジェクトは初期化時にself.viewに過剰にアクセスするためにクラッシュしました—ビュ―は作成されておらず、クラッシュにつながりました。


物語

大規模なプロジェクトでは、viewWillDisappear または deinit で NotificationCenter や delegate からの登録解除を忘れ、メモリリークを引き起こすことがありました(NotificationCenter がビューコントローラーを参照し、解放されずイベントを聞き続ける)。


物語

viewWillAppear では、各表示のたびにビューに新しいサブビュー(例えば、読み込みインジケーター)を追加し、存在を確認しませんでした。その結果、画面に戻るたびに重複するインジケーターが増え、UIが機能しなくなる事態を招きました。