使用 NSNotification 删除观察者...我做错了什么?
基本上,我有一个 view1,它在某个时候调用 view2 (通过 PresentModalViewController:animated: )。当按下 view2 中的某个 UIButton
时,view2 会调用 view1 中的通知方法,然后立即关闭。通知方法弹出警报。
通知方法工作正常并且被适当地调用。问题是,每次创建 view1 时(一次只能存在一个 view1),我可能会创建另一个 NSNotification ,因为如果我从 view0 (菜单)转到 view1,然后返回并创建连续几次,我从通知方法中收到一系列相同的警报消息,一次又一次,与我打开 view1 的次数一样多。
这是我的代码,请告诉我我做错了什么:
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];
}
Basically, I have a view1 which at some point, calls view2 (via presentModalViewController:animated:
). When a certain UIButton
in view2 is pressed, view2 is calls a notification method in view1 and immediately afterward is dismissed. The notification method pops up an alert.
The notification method works fine and is called appropriately. The problem is, every time view1 is created (only one view1 should exist at a time), I presumably get another NSNotification
being created because if I go from view0 (the menu) to view1, then back and forth a few times, I get a series of the same alert message, one after another, from the notification method as many times as I opened a view1.
Here is my code, please tell me what I'm doing wrong:
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];
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
视图控制器关闭后,调用
-dealloc
不会自动发生 - 视图控制器的生命周期中仍然可能存在一些“生命”。在该时间范围内,该视图控制器仍然订阅该通知。如果您在
-viewWillDisappear:
或-viewDidDisappear:
中删除观察者,这将产生更直接的效果:Calling
-dealloc
doesn't automatically happen after the view controller is dismissed — there can still be some "life" left in the view controller's lifetime. In that timeframe, that view controller is still subscribed for that notification.If you remove the observer in
-viewWillDisappear:
or-viewDidDisappear:
, this will have a more immediate effect:如果您在
viewWillDisappear:
或viewDidDisappear:
中实现了观察者的删除,那么您不应该在viewDidLoad
中保留观察者的添加。而是将观察者的添加放在
viewWillAppear:
中。您遇到的问题是因为当任何视图显示在UIViewController
视图上时,您的观察者将会被删除,并且由于您在viewDidLoad
中添加了观察者,这只会发生一次,就会丢失。请记住,当您的主视图不在最前面时,这种方法非常适合您不希望观察的对象。
另请记住,
viewDidUnload
也已被折旧。If you implement the removal of Observer in the
viewWillDisappear:
orviewDidDisappear:
then you should not leave the addition of the observer in theviewDidLoad
.Instead put the addition of the observer in the
viewWillAppear:
. The problem you are having is because when any view is shown onto of theUIViewController
view the removal of your observer will occur and since you added observer inviewDidLoad
which will happen only once, it will be lost.Keep in mind that this approach works well for objects you do not wish to observer while your main view is not in the fore front.
Also Keep in mind that
viewDidUnload
has been depreciated too.将
removeObserver:
放入dealloc
中没有任何问题。事实上它没有被调用意味着 view1 在关闭后没有正确释放。看起来有些东西保存着指向你的 view1 的指针,检查保留周期。另外,你不应该在 super 上调用 dealloc。
There is nothing wrong putting
removeObserver:
indealloc
. Just the fact it's not called means view1 not properly releases after dismissing. Looks like something holds pointer to your view1, check for retain cycles.Also, you shouldn't call dealloc on super.