2012-02-04 14 views
18

ユーザーが別のプログラムに切り替えた後にもう一度戻ると、元のプログラムのビューは別のプログラムの新しいビューに置き換えられます。だから、ユーザーが元のプログラムに戻ったとき、viewDidLoadを2度目に呼び出すのでしょうか?viewDidLoadはどのくらいの頻度で呼び出されますか?

このような場合は、ユーザーが画面を前後に切り替えるたびにviewDidLoad内に配置された初期化コードが実行されるため、これを尋ねています。そして、これはthe docsから...景色をresetingし、ユーザーの未完の作品を失うことに

+0

感謝を。 – Stanley

+4

コメントが正しくありません。最初の時刻だけでなく、ビューコントローラのビューが読み込まれるたびに呼び出されます。 –

+0

訂正ありがとう... – Stanley

答えて

26

viewDidLoadでビューコントローラの初期化を行わないでください。これはよくある間違いです。

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)bundleOrNil 
{ 
    if ((self = [super initWithNibName:nibNameOrNil bundle:bundleOrNil])) 
    { 
     //do your initialisation here 
    } 
    return self; 
} 

initWithNibName:bundle:メソッドはビューがからロードされ前と呼ばれる:ビューコントローラがロードされたときに一度だけ起こるべきもののため

は、このように、コントローラのinitメソッドでそれを行いますペンは、ビューコントローラの寿命の間に1回だけ呼び出されます。

コントローラーのビューは、コントローラーの寿命中に複数回ロードおよびアンロードでき、毎回viewDidLoadが呼び出されます。画面に表示されていないときはいつでもアンロードできます。通常はメモリが不足しています。

viewDidLoadに情報を設定した場合(例:サブビューをプログラムで追加する場合)は、viewDidUnloadに必ず設定を解除する必要があります。

ビューコントローラのビュープロパティのinit/deallocと同じように、viewDidLoadviewDidUnloadと考えてください。ビューに関連するものについては、それらのメソッドで作成してリリースします。コントローラ自体に関連するものについては、initWithNibNamedeallocに作成してリリースしてください。

UPDATE:(ビューが明示的にコード内でnilに設定されていない限り)のiOS 6で以降では、viewDidUnloadはそれ以上に呼び出されることはありませんし、そうviewDidLoadは通常、専用のビューコントローラの生活の中で一度呼び出されます。これにより上記のアドバイスはそれほど重要ではありませんが、それでもやはりベストプラクティスであり、iOS 5以前のバージョンをサポートする必要がある場合には必要です。

UPDATE 2:あなたの代わりに、プログラムを作成する(現在はお勧めです)ストーリーボードからあなたのビューコントローラをロードしている場合は、initWithNibName:bundle:が呼び出されることはありません。コントローラーを初期化するには、initWithCoder:またはawakeFromNibを使用してください。

+0

お返事ありがとうございました... – Stanley

+0

「このメソッドは、ビューがペン先からロードされる前に呼び出されました」、「これは」「initWithNibName」または「viewDidLoad」を参照してください。 – Stanley

+0

申し訳ありませんが、私はそれを明確にしました。 –

3

をもたらす可能性:ビューコントローラは、メモリにその関連のビューをロードした後

このメソッドが呼び出されます。

したがって、ビューコントローラがそのビューをメモリにロードすると、常に呼び出されます。これは、ビューがロードされて初めて再表示される場合や、ビューが常にアンロードされた場合にビューが可視になるたびに発生する可能性があります(メモリの制約などのためにviewDidUnload)。

+0

あなたの答えをありがとう... - – Stanley

4

-viewDidLoadは、そのビュー階層をロードする必要があります。明らかに、コントローラーがそのビューにアクセスするのは初めてです。ビューコントローラが後でそのビューをアンロードする場合、次にビューがロードされるときに-viewDidLoadが再び呼び出されます。ビューコントローラは、ビューが隠されているだけでそのビューをアンロードしませんが、メモリが不足し始めるとそうする可能性があります。

ビューコントローラはビ​​ューの状態を把握し、必要に応じて-viewDidLoadメソッドでそれらを設定できる必要があります。ビューは状態を格納するために使用されるべきではありません。ビューがアンロードされただけで元に戻すことはできません。

+1

あなたの詳細な返答ありがとう... – Stanley

+0

"ビューコントローラはビ​​ューの状態を知っている必要があります"この "国家を維持する能力"を尋ねたいと思っています。コードを使用するか、Cocoaライブラリに組み込まれていますか? – Stanley

+1

これは内蔵されていません。ポイントは、ビューコントローラがビューを保持して状態を保持するべきではないということです。たとえば、ビュー内にスライダがある場合は、スライダの値が変わるたびにそのスライダの値を覚えておく必要があります。このようにして、ビューがアンロードされてから再びロードされると、View Controllerはスライダーを-viewDidLoadの保存された値にリセットできます。 – Caleb

5

ユーザーが元のプログラムに戻ったときに、 viewDidLoadをもう一度呼び出すとしますか?

(以上、OPからのものである)

これらの場合に呼び出されるための2つの方法がある:

- (void)applicationWillEnterForeground:(UIApplication *)application; 

(タスクマネージャから、または再び踏み台からの)バックグラウンドにアプリを再開が
アプリがアクティブなときにロックされるロック解除デバイス。

- (void)applicationDidBecomeActive:(UIApplication *)application 

電話は(再びダブルタップホームボタン&ダブルタップ)
タスクマネージャ解雇
通知センターの解雇を呼び出した後

+0

あなたの詳細な答えをありがとう... – Stanley

17

@Nickロックウッドは優れた情報を提供していますが、覚えておくべきいくつかのより多くのものがあります。

まず、ビューコントローラがnibファイルまたはストーリーボードからインスタンス化されている場合、initWithNibName:bundle:は呼び出されません。その場合は、initWithCoder:awakeFromNibが代わりに呼び出されます。このような状況はiOSではやや珍しいものでしたが、ストーリーボードを追加すると、ビューコントローラがinitWithNibName:bundle:をバイパスするのがはるかに一般的になりました。

私は別の方法(私は私setupを呼び出す)とinitWithNibName:bundle:awakeFromNibの両方からそれを呼び出す非UIの初期化コードを置くことをお勧めします。しかし、初期化が一度だけ実行されることが重要な場合にのみこれを実行します。それ以外の場合は、私はそれをviewWillAppear:に入れて、できるだけレイジーロードにしてください。

第2に、self.viewinit...またはawakeFromNibに記載するものは実行しないでください。 は、viewDidLoadが呼び出されるまで決して参照するべきではありません。そうしないと、nibファイルが必要以上に早くロードされます。 UI関連のものは、ビューの設定に関連する場合はviewDidLoad、ビューの設定(つまりデータを読み込む場合)の場合はviewWillAppear:になります。

だから私は通常、これらの事を設定する方法:コメントを

@implementation 

- (void)setup { 
    // Non-UI initialization goes here. It will only ever be called once. 
} 

- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)bundle { 
    if ((self = [super initWithNibName:nibName bundle:bundle])) { 
    [self setup]; 
    } 

    return self; 
} 

- (void)awakeFromNib { 
    [self setup]; 
} 

- (void)viewDidLoad { 
    // Any UI-related configuration goes here. It may be called multiple times, 
    // but each time it is called, `self.view` will be freshly loaded from the nib 
    // file. 
} 

- (void)viewDidUnload { 
    [super viewDidUnload]; 
    // Set all IBOutlets to `nil` here. 
    // Drop any lazy-load data that you didn't drop in viewWillDisappear: 
} 

- (void)viewWillAppear:(BOOL)animated { 
    [super viewWillAppear:animated]; 
    // Most data loading should go here to make sure the view matches the model 
    // every time it's put on the screen. This is also a good place to observe 
    // notifications and KVO, and to setup timers. 
} 

- (void)viewWillDisappear:(BOOL)animated { 
    [super viewWillDisappear:animated]; 
    // Unregister from notifications and KVO here (balancing viewWillAppear:). 
    // Stop timers. 
    // This is a good place to tidy things up, free memory, save things to 
    // the model, etc. 
} 

- (void)dealloc { 
    // standard release stuff if non-ARC 
    [[NSNotificationCenter defaultCenter] removeObvserver:self]; // If you observed anything 
    // Stop timers. 
    // Don't unregister KVO here. Observe and remove KVO in viewWill(Dis)appear. 
} 

@end 
+0

詳細な答えをお寄せいただきありがとう... – Stanley

+1

あなたは実際にviewDidUnloadのサンプルを優れた例。 – Till

+0

@宜しくお願い致します。私はviewDidUnloadを含めることを忘れていました。一定。 –

関連する問題