ios 带有 NSNotification 的 removeObserver ......我做错了什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3328210/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
removeObserver with NSNotification... what am I doing wrong?
提问by Derek
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.
基本上,我有一个 view1,它在某个时候调用 view2(通过presentModalViewController:animated:
)。当UIButton
view2 中的某个被按下时,view2 会调用 view1 中的通知方法,然后立即解除。通知方法弹出警报。
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.
该通知方法工作正常,并适当调用。问题是,每次创建 view1 时(一次只应存在一个 view1),我大概会NSNotification
创建另一个,因为如果我从 view0(菜单)转到 view1,然后来回几次,我会得到一个一系列相同的警报消息,一个接一个,来自通知方法,就像我打开一个视图一样多。
Here is my code, please tell me what I'm doing wrong:
这是我的代码,请告诉我我做错了什么:
View1.m
查看1.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
视图2.m
-(IBAction) buttonWasTapped {
[[NSNotificationCenter defaultCenter] postNotificationName:@"alert"
object:nil];
[self dismissModalViewControllerAnimated:YES];
}
-(void) dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
回答by Alex Reynolds
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.
-dealloc
视图控制器被解除后调用不会自动发生——视图控制器的生命周期中仍然可以有一些“生命”。在那个时间范围内,该视图控制器仍然订阅该通知。
If you remove the observer in -viewWillDisappear:
or -viewDidDisappear:
, this will have a more immediate effect:
如果您删除-viewWillDisappear:
or中的观察者-viewDidDisappear:
,这将产生更直接的效果:
- (void) viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:@"alert"
object:nil];
}
回答by WhiteWabbit
If you implement the removal of Observer in the viewWillDisappear:
or viewDidDisappear:
then you should not leave the addition of the observer in the viewDidLoad
.
如果你在viewWillDisappear:
or 中实现了 Observer 的移除,viewDidDisappear:
那么你不应该在viewDidLoad
.
Instead put the addition of the observer in the viewWillAppear:
. The problem you are having is because when any view is shown onto of the UIViewController
view the removal of your observer will occur and since you added observer in viewDidLoad
which will happen only once, it will be lost.
而是将观察者的添加放在viewWillAppear:
. 您遇到的问题是因为当任何视图显示在UIViewController
视图上时,您的观察者都会被移除,并且由于您添加了viewDidLoad
只会发生一次的观察者,它将丢失。
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.
还要记住,它viewDidUnload
也已经折旧了。
回答by Almas Sapargali
There is nothing wrong putting removeObserver:
in dealloc
. 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.
没有什么错把removeObserver:
在dealloc
。事实上它没有被调用意味着 view1 在解雇后没有正确释放。看起来有些东西持有指向您的 view1 的指针,请检查保留周期。
Also, you shouldn't call dealloc on super.
此外,您不应该在 super 上调用 dealloc。