19

さまざまな Apple の例 (たとえば、Add Music ) を見ると、オブザーバーが のデフォルトに追加さNSNotificationCenterviewDidLoad、それらが で削除されていることがわかりますdeallocviewDidLoad呼び出されずに複数回呼び出される可能性があるため、これは危険に思えdeallocます。これにより、同じオブザーバーが複数回追加され、ハンドラーが複数回呼び出されます。

これに対する解決策は、 でオブザーバーも削除することですviewDidUnloadが、同じオブザーバーが で 2 回削除される可能性があることを意味し、deallocこれは潜在的な問題のようです。

私は何が欠けていますか?

4

5 に答える 5

25

正しい方法で通知を削除することについては、多くの議論があります。例えば:

viewWillDisappear(またはviewDidDisappear) およびviewDidUnloadライフサイクル メソッドのオブザーバーを削除することをお勧めします。(注: viewDidUnload非推奨であり、iOS6+ では実装すべきではありません。iOS 6 を参照してください - viewDidUnload migrate to didReceiveMemoryWarning? )

重要な注意:

viewDidUnloadが呼び出される保証はありません。これは標準的なライフサイクル メソッドではありません。

アップルのドキュメントから:

viewDidUnload メモリ不足の状態が発生し、現在のビュー コントローラーのビューが必要ない場合、システムはそれらのビューをメモリから削除することを選択する場合があります。このメソッドは、View Controller のビューが解放された後に呼び出され、最終的なクリーンアップを実行するチャンスです。

代わりに、deallocそのレシーバーの参照数がゼロになるたびに呼び出されます。

それが役に立てば幸い。

編集

完全を期すために、回避方法に関するこのリンクを参照できます-nsnotification-removeobserver。このリンクは、オブザーバーを削除するための便利なガイドラインを提供します (コメントも参照してください)。著者はviewDidAppear/viewDidDisappearメソッドでこれを行っており、多くのアプリケーションで常に正しく呼び出されるviewWillAppearとは限りません。viewWillDisappearそれはあなたの選択です。

オブザーバーを正しい方法で確実に削除したい場合は、deallocメソッドで登録解除するか、2番目のコメントで書いたようにビューが完全にアンロードされたときに登録を解除してください。しかし、それdeallocが将来的に呼び出されることを確認してください。つまり、既に述べたように、他のオブジェクトが参照しているためにコントローラーが存続し続けると、メソッドが呼び出されることはありません。この場合、コントローラは引き続き通知を受け取ります。

于 2012-04-26T13:45:50.190 に答える
2
- (void)viewWillAppear:(BOOL)animated
{
   [super viewWillAppear:animated];
   [[NSNotificationCenter defaultCenter] addObserver:self .........]
}

- (void)viewWillDisappear:(BOOL)animated
{
   [super viewWillDisappear:animated];
   [[NSNotificationCenter defaultCenter] removeObserver:self .........];
}
于 2013-12-23T07:19:45.687 に答える
1

viewWillAppear/でそれをしないのはなぜviewDidDisappearですか?とにかくビューが表示されているときの通知だけを気にしますよね?

于 2012-04-26T13:25:13.147 に答える