読者です 読者をやめる 読者になる 読者になる

UIViewController の init の中で self.view を参照しない方がいい

Xibファイルを使わずコードで書いてビューの生成を生成したいとき、ViewController の init メソッドの中で子ビューの初期化を下記の場所でしたくなるが、この時点ではベースとなる View 自体が生成されていないので、self.view を参照した時点でこの ViewController が実装する loadView, viewDidLoad が呼ばれてしまう。

- (id)init {
  if (self = [super init]) {
    // ここで子ビューの初期化
    // self.view を参照してはいけない
  }
}

たとえば、下記のようなコードだと(1),(2),(3)の順に実行されてしまう。

- (id)init {
  if (self = [super init]) {
    CGRect rect = self.view.bounds; //(1)
    UIView *subview = [[UIView alloc] initWithFrame:rect]; //(3)
    …
  }
}

- (void)loadView {
  //(2)
}

子ビューの生成は loadView で全て行うか、init では alloc, init にとどめ、位置、サイズかかわる設定は loadView 以降で行うこと。

サイズなどを決めうちで実装していて、上記の動作には気がついていなかった。
ということで初 iPhone SDK がらみのエントリーでした。