向 iOS/iPhone 用户发出关于重复 NSNotification 观察的警告

发布于 2024-09-06 13:30:23 字数 1146 浏览 4 评论 0原文

这与其说是一个问题,不如说是对其他人的警告,以节省他们一些时间。

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

迷爱 2024-09-13 13:30:23

你应该并且总是清理你的观察者。
最简单的方法是:[[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.

有木有妳兜一样 2024-09-13 13:30:23

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 调用之一,我将收到重复的通知到我的视图控制器。

在多线程环境中,这是一个充满伤害的世界。相信我。

只是把这个放在那里以防其他人遇到类似的事情。

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.

时光倒影 2024-09-13 13:30:23

正如您自己所说,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 :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文