web-dev-qa-db-ja.com

非推奨のiOS6 viewDidUnload

これは悪い習慣かもしれませんが、私が読んだドキュメントから、viewDidLoadメソッド内でオブジェクトを初期化し、viewDidUnloadでそれをnilするというアドバイスを受けました。

たとえば、オブザーバーを追加するようなものがある場合

[[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(filterready:)
                                                 name:@"filterReady"
                                               object:nil];

現在、Observerを削除するメソッドはありませんが、ビューが表示されるたびにviewDidLoadが呼び出されるため、しばらくすると複数のオブザーバーが実行され、セレクターが複数回呼び出されます。

いくつかのクリーナーをviewDidDisappearメソッドに移動することでこれを修正できますが、今は正しいことをしているのか疑問があります。

私のサンプルでは、​​サブナビゲーションを制御している複数のNavigation Controllerがありますが、それらが参照されていなくても、deallocは呼び出されません

60
Hons

- (void)didReceiveMemoryWarningおよび- (void)deallocメソッドを使用する必要があります。

IOS 6では、UIViewControllerのviewWillUnloadおよびviewDidUnloadメソッドは非推奨になりました。これらのメソッドを使用してデータを解放する場合は、代わりにdidReceiveMemoryWarningメソッドを使用します。また、このメソッドを使用して、View Controllerのビューへの参照が使用されていない場合は解放することもできます。これを行う前に、ビューがウィンドウ内にないことをテストする必要があります。

したがって、最初にビューがウィンドウ内にあるかどうかを確認してから、didReceiveMemoryWarning内のオブザーバーを削除する必要があります。

107
Alex Rouse

まず、viewDidUnloadが非推奨ではない場合でも、viewDidUnload AND deallocでその通知の登録を解除する必要がありました。 iOS 6以前でも、ほとんどの場合、viewDidUnloadは呼び出されません。低メモリ状況でのみ。そのため、以前にviewDidUnloadではなくdeallocにしか配置していなかった場合、登録は解除されず、割り当てを解除して通知を受信したときにクラッシュした可能性があります。したがって、正しく機能するためには、以前にdeallocに配置する必要がありました。

第二に、以前に正しく行っていた場合、iOS 6で正常に機能するために特別なことをする必要はありません。iOS6の唯一の違いは、ビューがまったくロードされないことです(メモリ不足の状況でも)。したがって、メモリ不足の状況に陥らなかったときのiOS 5と同じです。ビューはアンロードされないため、viewDidLoadは一度だけ呼び出され、通知は一度だけ登録されます。 deallocで登録解除されます。正しく機能するためには、それを配置する必要があります。

14
user102008

アレックスの答えは良いです。しかし、私は適切なペアリングが好きです。そのため、表示されていなくてもビューに通知する必要がない限り、通常はviewWillAppearおよびviewDidDisappearで通知を追加します

10
Anonymous White

DEALLOC関数でオブザーバーを削除しないのはなぜですか?また、ARCを使用している場合は、[super dealloc]を呼び出さないでください

コントローラーのdealloc関数が呼び出されない場合は、その理由を発見する必要があります。おそらく、ViewControllerでNSTimerを実行していて、ビューをポップすると、deallocが呼び出されない可能性があります。または、ビューは他の場所で保持されています。

4
Dan H