iPhone SDK:loadViewとviewDidLoadの違いは何ですか?


136

iPhoneアプリでビューとビューコントローラーを操作する場合、誰でもloadViewとviewDidLoadの違いを説明できますか?

私の個人的なコンテキストは、すべてのビューをコードから構築することです。私はInterface Builderを使用せず、今後も使用しません。

loadViewに初期化コードを追加すると、無限のスタックトレースが発生することがよくあるので、通常はすべての子ビューの構築をviewDidLoadで行いますが、それぞれがいつ実行されるかはわかりません。 initコードを配置するのにより適切な場所はどこですか。完璧になるのは、初期化呼び出しの簡単な図です。

ありがとう!

回答:


200

私はそれをしたので、ここで何が問題になるのかを推測できます:

loadViewに初期化コードを追加すると、無限のスタックトレースが発生することがよくあります

-loadViewのself.viewを読み取らないでください。設定するだけで、取得しないでください。

self.viewプロパティアクセサ、ビューが現在ロードされていない場合に-loadViewを呼び出します。あなたの無限の再帰があります。

AppleのPre-Interface-Builderの例で示されているように、-loadViewでプログラムによってビューを構築する通常の方法は、次のようになります。

UIView *view = [[UIView alloc] init...];
...
[view addSubview:whatever];
[view addSubview:whatever2];
...
self.view = view;
[view release];

そして、私はIBを使用しなかったとしてもあなたを責めません。私はすべてのInstapaperでこの方法にこだわっており、IBの複雑さ、インターフェースの癖、および予期しない舞台裏の動作を処理するよりもずっと快適だと感じています。


ああ、最後に説明ありがとうございます!一時変数を割り当ててからself.viewに設定してから解放するという慣用句を回避しました。どういうわけか、不便で不必要に思えました。私は今、その決定が私を今自分自身を見つける道へと導いた理由を理解することができます。
ryan.scott 2009

私にはそのようなコードがあり、再帰はありません。どうして?-(void) loadView { // Frame for Hypnosis view CGRect frame = [[UIScreen mainScreen] bounds]; // Create a Hipnosis view v = [[HypnosisView alloc] initWithFrame:frame]; self.view = v;
user2054339 2013

44

loadViewUIViewControllerビューを実際にロードしてviewプロパティに割り当てるメソッドです。これは、UIViewControllerプログラムでviewプロパティを設定する場合に、サブクラスがオーバーライドする場所でもあります。

viewDidLoadビューが読み込まれると呼び出されるメソッドです。これは、loadViewが呼び出された後に呼び出されます。これは、ロードされた後、ビューの初期設定をさらに行うコードをオーバーライドおよび挿入できる場所です。


14
viewDidLoad()

NIBからビューをロードし、起動後にカスタマイズを実行する場合に使用します

LoadView()

プログラムでビューを作成する場合に使用します(Interface Builderを使用せずに)


これには問題がある可能性があります。ビューコントローラーがNIBファイルに関連付けられていないときにテストしましたが、viewDidLoadがまだ呼び出されています
ruandao

11

NilObjectが言ったことを示すために、いくつかのコード例を追加するだけです。

- (void)loadView
{
    // create and configure the table view
    myTableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] style:UITableViewStyleGrouped];   
    myTableView.delegate = self;
    myTableView.dataSource = self;
    myTableView.scrollEnabled = NO;
    self.view = myTableView;

    self.view.autoresizesSubviews = YES;
}

- (void)viewDidLoad 
{
  self.title = @"Create group";

  // Right menu bar button is to Save
  UIBarButtonItem *saveButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Save" style:UIBarButtonItemStyleDone target:self action:@selector(save)];
  self.navigationItem.rightBarButtonItem = saveButtonItem;
  [saveButtonItem release];
}

4
したがって、2人の間では、loadViewがコントローラーのself.viewのalloc / initを実行する場所であり、子ビューはviewDidLoad(またはそれ以降)で処理する必要があると言って間違いありませんか?
ryan.scott 2009

2

self.viewを読み取るときに無限ループが発生しないようにするには、ビューをロードするときにクラスのスーパー実装を呼び出します。スーパー実装は新しいUIViewを割り当てます。

- (void) loadView {
[super loadview];

// init code here...

[self.view addSubView:mySubview1]; //etc..

}

6
私はあなたが電話してはいけないと言ったアップルのドキュメントを誓うことができます[super loadView];。例ではそれは矛盾していましたが、ドキュメントはそれを正しく言っていたと思います(時間の経過とともに例の中に多数のバグを発見しました)。[super loadView]ただし、UITableViewControllerなどには必要です。しかしながら!ロード後のセットアップ(サブビューの追加など)は、viewDidLoadで行う必要があります。
IvanVučica11年

これまで副作用なしに[super loadView]を呼び出しました。自分で作成したものにself.viewを設定するつもりなら、それは本当かもしれません。
futureelite7 2011年

loadView内で[super loadView]を呼び出すと、デフォルト名で使用可能な場合は、nibからビューをロードしようとします。したがって、注意する必要があります。
Ian1971

[super loadView]を呼び出すと、super loadViewメソッドでself.viewを初期化します
Alex Nazarsky

1

loadViewを使用する最も簡単な方法は、UIViewControllerのサブクラスであるMyBaseViewControllerのような、ある種のベースビューコントローラを作成することです。そのloadViewメソッドでは、このようにビューを作成します:

-(void) loadView {
    if ([self viewFromNib]) {
        self.view = [self viewFromNib];
    } else {
        self.view = [[[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    }
    self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight;
    self.view.backgroundColor = [UIColor whiteColor];
}

そして、いくつかのビューコントローラーを作成する必要がある場合、MyBaseViewControllerのサブクラスを使用し、そのloadViewコントローラーでは、次のように[super loadView]を呼び出すだけ

//sucblass loadView
-(void) loadView {
    [super loadView];

    //rest of code like this..
    UILabel *myLabel = [[UILabel alloc] initWithFrame:myFrame];
    [self.view addSubview:myLabel];
    [myLabel release];
}

1

loadView()コントローラーの作成を要求されたときに呼び出されますself.view。あなたは自分でそれを行うことができます

self.view = [UIView alloc] init...];

または、コントローラーの親UIControllerクラスに-loadView()、self.viewを空白のビューに初期化するメソッド名が既にあります。その後、あなたは呼び出すことができます

[super loadView];

2番目のアプローチは継承を促進するので、私は本当にお勧めします。ビューコントローラーがUIViewControllerから直接継承されていない場合のみ。


0

AppleがviewDidLoadに与えた定義では、コントローラーのビューがメモリに読み込まれた後に呼び出されると述べています。簡単に言えば、ロードされる最初のメソッドです。

この方法が十分に活用されるのはどのような条件下で考えているのでしょうか?答えは、基本的に、アプリに最初にロードさせたいものすべてです。たとえば、白ではなく別の背景色が必要な場合は、青を選択できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.