向 iOS/iPhone 用户发出关于重复 NSNotification 观察的警告
这与其说是一个问题,不如说是对其他人的警告,以节省他们一些时间。
iOS 3/iPhone OS 3 上的 NSNotificationCenter(我假设还有 Mac OS X 和 iOS 4)具有以下行为:
如果您多次注册自己以获取确切的特定通知,NSNotificationCenter 将不识别该通知冗余,而是会向您发出与您注册观察一样多的通知。
这几乎不是您希望看到的行为,而且几乎总是意外的。
示例:
我希望我的视图控制器在新数据传入时接收来自单例网络对象的通知:
- (void) viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(newDataArrived:)
name:NewDataArrivedNotification
object:[NetworkListener sharedNetworkListener]];
}
但之前我已经将相同的内容放入 viewWillAppear
中:
- (void) viewWillAppear
{
[super viewWillAppear];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(newDataArrived:)
name:NewDataArrivedNotification
object:[NetworkListener sharedNetworkListener]];
}
请注意,它完全正确
在这种情况下,如果我不删除这些 addObserver 调用之一,我将收到重复的通知到我的视图控制器。
在多线程环境中,这是一个充满伤害的世界。相信我。
只是把这个放在那里以防其他人遇到类似的事情。
This isn't a question so much as a warning to others to save them some time.
NSNotificationCenter on iOS 3/iPhone OS 3 (I'm assuming also Mac OS X and iOS 4) has the following behavior:
If you register yourself multiple times for the exact specific notification, NSNotificationCenter will NOT recognize the redundancy and instead will fire off as many notifications to you as you've registered an observation for.
This is almost never the behavior you want to see and is almost always accidental.
Example:
I want my view controller to receive notifications from a singleton network object when new data comes in:
- (void) viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(newDataArrived:)
name:NewDataArrivedNotification
object:[NetworkListener sharedNetworkListener]];
}
but earlier I'd already put the same thing in viewWillAppear
:
- (void) viewWillAppear
{
[super viewWillAppear];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(newDataArrived:)
name:NewDataArrivedNotification
object:[NetworkListener sharedNetworkListener]];
}
Note that it's exactly the same notification, resolving to the same observer, sender and notification name.
In this case, if I don't remove one of those addObserver calls, I'll get duplicate notifications to my view controller.
In a multi-threaded environment, this is a world of hurt. Trust me.
Just putting this out there in case there are others who run into something like this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你应该并且总是清理你的观察者。
最简单的方法是:[[NSNotificationCenterdefaultCenter]removeObserver:self]
viewDidLoad 不是添加观察者的好地方,因为该函数可能会被多次调用,这种情况在触发 viewDidUnload 时发生。
一个将 addObservers 放在 viewWillAppear 中、将 removeObservers 放在 viewWillDisappear 中的好地方。
You should and always clean up your observers.
The easiest way to do it is : [[NSNotificationCenter defaultCenter] removeObserver:self]
viewDidLoad is not a good place to add observers, because this functions may get called multiple times, this happens when viewDidUnload is triggered.
A good place to put your addObservers in viewWillAppear, and removeObservers in viewWillDisappear.
iOS 3/iPhone OS 3 上的 NSNotificationCenter(我假设还有 Mac OS X 和 iOS 4)具有以下行为:
如果您多次注册自己以获取确切的特定通知,NSNotificationCenter 将不识别该通知冗余,而是会向您发出与您注册观察一样多的通知。
这几乎不是您希望看到的行为,而且几乎总是意外的。
示例:
我希望我的视图控制器在新数据传入时接收来自单例网络对象的通知:
但之前我已经将相同的内容放入
viewWillAppear
中:请注意,它完全正确
在这种情况下,如果我不删除这些 addObserver 调用之一,我将收到重复的通知到我的视图控制器。
在多线程环境中,这是一个充满伤害的世界。相信我。
只是把这个放在那里以防其他人遇到类似的事情。
NSNotificationCenter on iOS 3/iPhone OS 3 (I'm assuming also Mac OS X and iOS 4) has the following behavior:
If you register yourself multiple times for the exact specific notification, NSNotificationCenter will NOT recognize the redundancy and instead will fire off as many notifications to you as you've registered an observation for.
This is almost never the behavior you want to see and is almost always accidental.
Example:
I want my view controller to receive notifications from a singleton network object when new data comes in:
but earlier I'd already put the same thing in
viewWillAppear
:Note that it's exactly the same notification, resolving to the same observer, sender and notification name.
In this case, if I don't remove one of those addObserver calls, I'll get duplicate notifications to my view controller.
In a multi-threaded environment, this is a world of hurt. Trust me.
Just putting this out there in case there are others who run into something like this.
正如您自己所说,NSNotificationCenter 不检查重复项,这对某些人来说可能很烦人,但在考虑其背后的完整系统时是有意义的。
相同的逻辑适用于向某些对象添加目标,但通常对这些对象有一个关键的识别。
感谢您的洞察力,以及对 SEO 友好的良好警告:)
As you said yourself, NSNotificationCenter makes no check for duplicates, which may be annoying for some, but makes sense when concidering the full system behind it.
The same logic applies to adding targets to certain objects, but there is often a key recognition on those.
Thank you for the insight, and for a good, SEO-friendly warning :)