addObserverおよびremoveObserverメソッドを呼び出す可能な場所
-
03-07-2019 - |
質問
子ビューが親ビューに通知を送信する場合があります。 viewWillAppear:
で addObserver:
を呼び出し、 viewWillDisappear:
で removeObserver:
を呼び出しています。しかし、ビューが更新されると viewWillAppear:
が呼び出されるため、これは正しくないと推測しています。
[[NSNotificationCenter defaultCenter] addObserver: (id)observer selector: (SEL)aSelector name: (NSString *)aName object: (id)anObject];
[[NSNotificationCenter defaultCenter] removeObserver: (id)observer name: (NSString *)aName object: (id)anObject];
ありがとう。
解決
実際、これは悪い考えです。メモリが少なくなると、View Controllerがメモリ警告を送信する場合があります。このインスタンスのデフォルトの動作は、ビューをクリアすることです(現在画面にいない場合)。この場合、2回目にviewDidLoadメッセージを送信することができます(メモリイベントの後、ナビゲーションコントローラーによってビューが画面に戻されたとき)。したがって、同じオブジェクトの2つの登録がありますが、削除は1つだけです。 (deallocで)
より良い解決策は、登録済みであることを示すフラグを設定するか、initメソッドで登録することです。
他のヒント
通知に登録する正しい位置は viewDidLoad
メソッドで、同じ通知に登録を解除する正しい位置は dealloc
メソッドだと思います。
Benの権利-しかし、私は別の、潜在的に壊れやすい方法を見つけました。これは、キー値オブザーバーがまだ登録されている間、「...」が永久に解除されていたために発見されました
理由はわかりませんが、initメソッドにaddObserverがあり、deallocメソッドにremoveObserverがあると、KVOがまだ監視されているというメッセージが表示されていました。ステップを実行して、removeObserverが正しく呼び出されていることを確認しました。
代わりにaddobserverをviewDidLoadメソッドに移動しましたが、動作しているように見えました。
viewDidUnloadにremoveObserverを残し、deallocに を残しました。しかし、バランスが取れていないので、私はそれが好きではありません。ただし、通常の状況では、viewDidUnloadは呼び出されません。これは、メモリ不足の通知を受け取った場合の保護にすぎません。
しかし、潜在的にメモリ不足のイベントが発生し、viewDidUnloadが呼び出される状況になる可能性があります。その後、deviewを押すと(viewDidLoadをもう一度押す前に)、removeObserverを2回呼び出します。
だから、viewDidLoadとdeallocに保存するだけだと思います。
initメソッドでaddobserverを実行すると、なぜ正しく動作しないのかまだわかりません。