Hatena::Groupiphone-dev

Ni chicha, ni limona - 平均から抜けられない僕

2009-06-29

[iPhone] UIViewControllerの各メソッドの役割おさらい 01:11  [iPhone] UIViewControllerの各メソッドの役割おさらい - Ni chicha, ni limona - 平均から抜けられない僕 を含むブックマーク はてなブックマーク -  [iPhone] UIViewControllerの各メソッドの役割おさらい - Ni chicha, ni limona - 平均から抜けられない僕  [iPhone] UIViewControllerの各メソッドの役割おさらい - Ni chicha, ni limona - 平均から抜けられない僕 のブックマークコメント


※ほしさんのコメントを受けて、ビューが実際にロードされるタイミング周りの内容を追記&修正しました。ほしさん、ありがとうございます。


このブログを読んでいる方ならば、一番お世話になっているんじゃないかと思うCocoa touchのクラスUIViewController。画面上に表示するビューを管理する上で欠かせないクラスです。


ただ、このUIViewControllerアプリには初期化時に呼ばれる可能性のあるメソッドが大量にあり、どれがいつ使われるのか、ある処理はどのメソッドに記述するべきかといった点で迷うのも事実だと思います。はい、まさしくボクがそんな状態です。


「これじゃいつまで経っても初心者のままだ」と思い、ちょっとまとめてみることにしました。出典はAppleのオンラインドキュメントと、後述する「iPhoneアプリケーションプログラミング*1」です。


メソッド名機能
-initWithNibName: bundle:指定したXIBファイルを開くための初期処理を実行。IBで作成したxibファイルを読み込むための前準備。ただし、まだこの時点ではnibファイルはロードされていないので注意
viewメソッドorプロパティビューを実際に表示するときにもちいるプロパティ。このプロパティへのアクセスによって、ビューのロード処理が始まる。
-loadViewUIViewControllerクラスのviewプロパティが必要とされたタイミングにviewが無指定だった場合(initWithNibNameでxibファイルを指定していなかった場合、またはviewコール前にsetViewしていなかった場合)、フレームワークによって自動的に呼ばれるメソッド(=自分で直接呼んだらダメ)。ビュー作成にIBを使わず、マニュアルで作りたい場合にはここで作る
-viewDidLoad initWithNibName: bundle:でxibファイルが開かれたら、まず呼ばれるメソッド。画像等はまだ画面上に表示されていない
-viewWillAppear: animated:ビューが画面上に表示される直前に呼ばれるメソッド。
-viewDidAppear: animated:ビューが画面上に表示された直後に呼ばれるメソッド。

なるほど。順番で言うと


  1. -initWithNibName: bundle:
  2. (-setViewによるUIView*系クラスのセット)
  3. viewプロパティへのアクセス or viewメソッドのコール
  4. (-loadView) ← Nibファイルを指定していなかった場合 or setViewしていなかった場合
  5. -viewDidLoad
  6. -viewWillAppear: animated:
  7. 《画面表示》
  8. -viewDidAppear: animated:
  9. 《完了!ユーザー操作が可能に》

となるんだ。

ということはloadViewはviewに何も指定されていないときに呼ばれるわけで、xibファイルがロードされた場合には呼ばれない。なので、このloadViewメソッドではビュー(V&C)に注目した処理を書くと良さそう。

そしてデータ(M)の初期化などの準備は、-initWithNibName: bundle:を呼んでいる処理の中か、もしくは-viewDidLoadで行うのが行儀良いのかな、たぶん(ちょっと自信がないけど、前者の方がタイミング的にいいのかも)。


文にまとめてみたら、だいぶん分かるようになりました。ポイントは、

  • -initWithNibNameの段階ではまだロードされない
  • viewプロパティorゲッターにアクセスされたときに初めてビューがロードされる
  • 自分でビューをセットアップしたい場合は-initWithNibNameでnilを設定しておいて、-loadView内でセットアップする

というあたりかな。


ちなみに

今回のおさらいには、書籍「iPhoneアプリケーションプログラミング*2」が役に立ちました。この本では、Cocoa touchで提供されている各クラスについて、


  • どういうときに使って
  • 提供するメソッドには何があって
  • それぞれどういう意味があるのか

が丁寧に書かれています。

プログラミングについてを「はじめてのiPhoneプログラミング*3」で学んだあとは(もしくは学びつつ)、この本で各クラスの理解を深めるのが近道だと思います。

(という流れで下のリンクを貼っていますが、勘弁してくださいませ)


 Website Temporarily Unavailable

  (Amazonインスタントストアへのリンク)


それにしても、iPhoneアプリを作る本は本当に増えてきました。私みたいにどんどん買うのもどうかと思いますので、皆さんはうまく情報を取捨選択していってください。

*1:注意:Amazonインスタントストアへのリンクです。

*2:注意:Amazonインスタントストアへのリンクです。

*3:これもそう。

ほしほし2009/06/30 05:05-initWithNibName:bundle: は xib ファイルを指定してビューコントローラを初期化するだけで、xib ファイルの読み込み (view の生成) は行いません。view の生成は view メソッド (プロパティ) が最初に呼ばれたときに loadView が呼ばれることによって行われます。たしか。(iPhone ではメモリを節約するために、本当に必要になるまでオブジェクトを作らないことが推奨されています。)

paellapaella2009/06/30 07:02コメントありがとうございます。なるほど、initWithNibNameはコントローラの初期化だけで、loadviewが呼ばれる(いよいよビューが必要になる)のはviewのゲッター(プロパティ)が呼ばれたときなんですね。

「初めてviewプロパティを使った時はどうも遅いな」と感じていた理由が分かりました。ありがとうございました。

KishikawaKatsumiKishikawaKatsumi2010/07/28 00:55データの初期化について、init は1回きりですが、viewDidLoad はライフサイクルの中で何度も呼ばれる可能性があるところが注意ですね。
繰り返し呼ばれても問題ないようにしておかないとリークしたりします。

paellapaella2010/07/28 01:27ありがとうございます。
読み返してみると、最初に動き始めるときの内容には注目しているものの、その後動いているときの振る舞いについては書いてありませんね。

書かねば。。。

JoeJoe2012/05/30 12:00God help me, I put aside a whole afetrnoon to figure this out.

uaruetjtyuaruetjty2012/05/30 18:24brBzX2 <a href="http://ejnkigxcfmet.com/">ejnkigxcfmet</a>

cnntmwcefcnntmwcef2012/06/01 00:317q5y4Z <a href="http://jidyxyoovhra.com/">jidyxyoovhra</a>

cpkhrbqicpkhrbqi2012/06/01 19:354a0ijC , [url=http://trwiwrucdnnu.com/]trwiwrucdnnu[/url], [link=http://kqcjjfkceyeg.com/]kqcjjfkceyeg[/link], http://nqoocquivfwr.com/

NobeNobe2012/11/22 12:29助かりました。ファイル名指定でinitして、”loaded XXXXX nib but the view outlet was not set.”が出続けていました。