ios 为什么我的 NSNotification 其观察者被多次调用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19801645/
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
Why is my NSNotification its observer called multiple times?
提问by BarryK88
Within an App I make use of several viewcontrollers. On one viewcontroller an observer is initialized as follows:
在一个应用程序中,我使用了几个视图控制器。在一个视图控制器上,观察者初始化如下:
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"MyNotification" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(myMethod:) name:@"MyNotification" object:nil];
Even when removing the NSNotification
before initializing the number of executions of myMethod:
is being summed up by the amount of repeated views on the respective viewcontroller.
即使NSNotification
在初始化之前删除 的执行次数myMethod:
也会通过相应视图控制器上的重复视图数量相加。
Why does this happen and how can I avoid myMethod: being called more then once.
为什么会发生这种情况以及如何避免 myMethod: 被多次调用。
Note: I made sure by using breakpoints that I did not made mistakes on calling postNotification multiple times.
注意:我通过使用断点确保在多次调用 postNotification 时没有出错。
Edit: This is how my postNotification looks like
编辑:这就是我的 postNotification 的样子
NSArray * objects = [NSArray arrayWithObjects:[NSNumber numberWithInt:number],someText, nil];
NSArray * keys = [NSArray arrayWithObjects:@"Number",@"Text", nil];
NSDictionary * userInfo = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
[[NSNotificationCenter defaultCenter] postNotificationName:@"myNotification" object:self userInfo:userInfo];
edit: even after moving my subscribing to viewwillappear: I get the same result. myMethod: is called multiple times. (number of times i reload the viewcontroller).
编辑:即使将我的订阅移至 viewwillappear:我得到相同的结果。myMethod:被多次调用。(我重新加载视图控制器的次数)。
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"MyNotification" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(myMethod:) name:@"MyNotification" object:nil];
}
edit: something seems wrong with my lifecycle. ViewDidUnload and dealloc are not getting called, however viewdiddisappear is getting called.
编辑:我的生命周期似乎有问题。ViewDidUnload 和 dealloc 没有被调用,但是 viewdiddisappear 被调用。
The way I push my Viewcontroller to the stack is as follows where parent is a tableview subclass (on clicking the row this viewcontroller is initiated:
我将我的 Viewcontroller 推送到堆栈的方式如下,其中 parent 是 tableview 子类(单击此视图控制器启动的行:
detailScreen * screen = [[detailScreen alloc] initWithContentID:ID andFullContentArray:fullContentIndex andParent:parent];
[self.navigationController pushViewController:screen animated:YES];
Solution:
解决方案:
Moving removal of nsnotification to viewdiddisappear did the trick. Thanks for guidance!
将 nsnotification 的移除移至 viewdiddisappear 就行了。谢谢指导!
回答by Jaanus
Based on this description, a likely cause is that your viewcontrollers are over-retained and not released when you think they are. This is quite common even with ARC if things are over-retained. So, you think that you have only one instance of a given viewcontroller active, whereas you actually have several live instances, and they all listen to the notifications.
根据此描述,一个可能的原因是您的视图控制器被过度保留,并且没有在您认为的时候释放。如果过度保留,即使使用 ARC,这也很常见。因此,您认为您只有一个给定视图控制器的实例处于活动状态,而实际上您有多个活动实例,并且它们都在监听通知。
If I was in this situation, I would put a breakpoint in the viewcontroller's dealloc method and make sure it is deallocated correctly, if that's the intended design of your app.
如果我处于这种情况,我会在视图控制器的 dealloc 方法中放置一个断点,并确保它被正确释放,如果这是您的应用程序的预期设计。
回答by Igor
In which methods did you register the observers?
你在哪些方法中注册了观察者?
Apple recommends that observers should be registered in viewWillAppear:
and unregistered in viewWillDissapear:
Apple 建议观察者应该viewWillAppear:
在viewWillDissapear:
Are you sure that you don't register the observer twice?
你确定你没有注册观察者两次吗?
回答by abhi
Ran into this issue in an application running swift. The application got the notification once when first launched. the notification increases the number of times you go into the background and come back. i.e
在 swift 运行的应用程序中遇到了这个问题。该应用程序在首次启动时收到一次通知。通知会增加您进入后台并返回的次数。IE
- app launches one - add observer gets gets called once in view will appear or view did load - notification is called once
- app goes into background and comes back, add observer gets called again in view will appear or view did load. notification gets called twice.
- the number increases the number of times you go into background and come back.
- code in view will disappear will make no difference as the view is still in the window stack and has not been removed from it.
- 应用程序启动一个 - 添加观察者被调用一次在视图中将出现或视图加载 - 通知被调用一次
- 应用程序进入后台并返回,添加观察者在视图中再次被调用将出现或视图已加载。通知被调用两次。
- 该数字会增加您进入后台并返回的次数。
- 视图中的代码将消失不会有任何区别,因为视图仍在窗口堆栈中并且尚未从中删除。
solution: observe application will resign active in your view controller:
解决方案:观察应用程序将在您的视图控制器中退出活动:
NSNotificationCenter.defaultCenter().addObserver(self, selector: "applicationWillResign:", name: UIApplicationWillResignActiveNotification, object: nil)
func applicationWillResign(notification : NSNotification) {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
this will make sure that your view controller will remove the observer for the notification when the view goes into background.
这将确保您的视图控制器将在视图进入后台时移除通知的观察者。
回答by lead_the_zeppelin
it is quite possible you are subscribing to the notifications
您很有可能订阅了通知
[[NSNotificationCenter defaultCenter] postNotificationName:@"myNotification" object:self userInfo:userInfo];
before selfgets initialized. And trying to unsubscribe 'self' which isn't really subscribed to, and you will get all global myNotificationnotifications.
在self被初始化之前。并尝试取消订阅未真正订阅的“self”,您将收到所有全局myNotification通知。
If your view was hooked up in IB, use -awakeFromNib:as the starting point to register for notifications
如果您的视图已连接到 IB,请使用-awakeFromNib:作为注册通知的起点
回答by Murray Sagal
It is possible that the class with the observer is, quite appropriately, instantiated multiple times. When you are debugging it will kinda look like the notification is being posted multiple times. But if you inspect self
you might see that each time is for a different instance.
带有观察者的类可能被多次实例化。当您调试时,它看起来像是多次发布通知。但是,如果您进行检查,self
您可能会发现每次都针对不同的实例。
This could easily be the case if your app uses a tab bar and the observer is in a base class of which your view controllers are subclasses.
如果您的应用程序使用标签栏并且观察者位于您的视图控制器是其子类的基类中,则很容易出现这种情况。