loadViewとviewDidLoadとself.view
nibを使わずにViewControllerを作成するとき、なんとなくnibを使う時と同じように「viewDidLoad」内で、Viewを作成してaddSubViewしていました。
これでとくに問題なく動いていたんだけど、loadViewメソッドのところに書いてある、このコメントが気になったんです。
// Implement loadView to create a view hierarchy programmatically, without using a nib.
nibを使わない時は、ここでViewを作成しなくちゃだめなの?
というわけで、こんなコードを書いてみたら、
- (void)loadView {
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
label.text = @"TEST";
[self.view addSubview:label];
[label release];
}
EXC_BAD_ACCESSいただきましたー!
loadViewが呼ばれた時には、「self.view」が存在しないんですね。なので、自分で「self.view」自体を作ってあげる必要があります。
- (void)loadView {
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
label.text = @"TEST";
self.view = label;
[label release];
}
こんな感じで。
だとするとですよ、viewDidLoadの時に「self.view」ができてるのはなぜなのか?
そこで、こんなコードを書いてみました。
- (void)loadView {
self.view = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)] autorelease];
}
- (void)viewDidLoad {
[super viewDidLoad];
if (self.view) {
NSLog(@"viewDidLoad:self.view=%@", self.view);
} else {
NSLog(@"viewDidLoad:self.view=nil");
}
}
こうすると、コンソールには、
2010-11-19 14:30:13.681 test[5744:207] viewDidLoad:self.view=<UIView: 0x5f4de50; frame = (0 0; 100 100); layer = <CALayer: 0x5f4de80>>
こんな表示がでます。
次にloadViewをコメントアウト。
/*
- (void)loadView {
self.view = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)] autorelease];
}
*/
- (void)viewDidLoad {
[super viewDidLoad];
if (self.view) {
NSLog(@"viewDidLoad:self.view=%@", self.view);
} else {
NSLog(@"viewDidLoad:self.view=nil");
}
}
こうすると
2010-11-19 14:31:40.486 test[5837:207] viewDidLoad:self.view=<UIView: 0x5f3f4a0; frame = (0 20; 320 460); autoresize = W+H; layer = <CALayer: 0x5f3f4d0>>
こんな表示に!
なんか、自動的にViewが作られてる!!
もしかすると、ベースとなるViewを自分できちんと用意したい時には「loadView」を使わないといけないけど、とりあえず用意されてるViewでいいやーって時は、viewDidLoadを使えばいいのかも。
確かに、メソッドの名前的にも、そんな気がしてきた。
個人的には、viewDidUnloadとの対比を考えると、viewDidLoadでボタンやらラベルやらのViewを追加して、viewDidUnloadでそれらを解放とした方がすっきりするかなぁ、と。
おそらく自動的に作られる「self.view」については、ViewController自身が良きに計らってくれるのではないかと想像したりして。
どうなんだろうなぁ。
検索してもあまり情報が出てこなかったので、まとめてみました。
ご意見おまちしておりますー。
【追記】
これ、僕の勘違いでした!
- (void)loadView {
[super loadView];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
label.text = @"TEST";
[self.view addSubview:label];
[label release];
}
[super viewLoad]をすればオッケーでした!!
テンプレートのコードに入っていなかったので、うっかりしてました。
コメントしてくださった、けいたんさんありがとうございました!
投稿者 CHEEBOW : 2010年11月19日 14:45
Tweet
[ Development, iPhone ]
【お知らせ】音楽に関することはこちらのブログで書いています。くじら音楽部::BLOG
