基本的に、私はある時点で(presentModalViewController:animated:
を介して)view2を呼び出すview1を持っています。 view2の特定のUIButton
が押されると、view2はview1の通知メソッドを呼び出し、直後に閉じられます。通知メソッドはアラートをポップアップします。
通知メソッドは正常に機能し、適切に呼び出されます。問題は、view1が作成されるたびに(一度に1つのview1のみが存在する必要がある)、おそらく別のNSNotification
が作成されることです。なぜなら、view0(メニュー)からview1に移動すると、何度か、ビューを開いた回数と同じ回数、一連の同じアラートメッセージが通知メソッドから次々と表示されます1。
これが私のコードです、私が間違っていることを教えてください:
View1.m
-(void) viewDidLoad {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(showAlert:)
name:@"alert"
object:nil];
}
-(void) showAlert:(NSNotification*)notification {
// (I've also tried to swap the removeObserver method from dealloc
// to here, but it still fails to remove the observer.)
// < UIAlertView code to pop up a message here. >
}
-(void) dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
View2.m
-(IBAction) buttonWasTapped {
[[NSNotificationCenter defaultCenter] postNotificationName:@"alert"
object:nil];
[self dismissModalViewControllerAnimated:YES];
}
-(void) dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
-dealloc
の呼び出しは、ビューコントローラーが閉じられた後に自動的に行われるわけではありません。ビューコントローラーのライフタイムには、まだ「ライフ」が残っている可能性があります。その時間枠では、そのビューコントローラーはその通知に対してまだサブスクライブされています。
-viewWillDisappear:
または-viewDidDisappear:
でオブザーバーを削除すると、より即時に効果があります。
- (void) viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:@"alert"
object:nil];
}
オブザーバーの削除をviewWillDisappear:
またはviewDidDisappear:
に実装する場合、オブザーバーの追加をviewDidLoad
のままにしないでください。
代わりに、オブザーバーの追加をviewWillAppear:
に入れます。あなたが抱えている問題は、UIViewController
ビューにビューが表示されるとオブザーバーの削除が発生し、viewDidLoad
にオブザーバーを追加したのは1回だけなので、失われた。
このアプローチは、メインビューが前面にないときに、観察したくないオブジェクトに適していることに注意してください。
また、viewDidUnload
も減価償却されていることに注意してください。
dealloc
にremoveObserver:
を入れるのは問題ありません。それが呼び出されないというだけの事実は、view1が却下後に適切に解放されないことを意味します。何かがビュー1へのポインタを保持しているようです。保持サイクルを確認してください。
また、スーパーでdeallocを呼び出すべきではありません。