« 2010年10月 | メイン | 2010年12月 »

2010年11月19日

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 : 14:45

[ Development, iPhone ]

2010年11月29日

電子書籍「Sohzine Vol.1」に小説を寄稿しました

電子書籍「Sohzine Vol.1」に僕の書いた短編小説が収録されています。

Sohzine Vol.1 | eBook Cast

いわゆる奇妙な味の短編なんじゃないかなと思います。世にも奇妙な物語が好きな方はぜひ!
本名の関根 元和名義で書いてます。「本読人」という作品です。

もともと、オンラインマガジン騒人で発表したものが、今回めでたく電子書籍化された、というわけ。

おすすめネット小説と電子書籍のオンラインマガジン騒人

ePUB形式なので、

Adobe - Digital Editions

こんなビュワーを使うとPCやMacでも見られますし、

アップル - iPad - まったく新しい方法で読書をしましょう。

iBookを使えば、iPhoneやiPadでも読めます。
僕の作品以外もおすすめですので、ぜひ!
なんと無料で読めます。
電子書籍入門としても良いのではないかと思いますよー。

投稿者 CHEEBOW : 23:58

[ Write ]