21

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

iOS 3/iPhone OS 3(我假设也是 Mac OS X 和 iOS 4)上的 NSNotificationCenter 具有以下行为:

如果您为确切的特定通知多次注册,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 调用,我将收到重复通知到我的视图控制器。

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

只是把它放在那里,以防其他人遇到这样的事情。

4

3 回答 3

3

iOS 3/iPhone OS 3(我假设也是 Mac OS X 和 iOS 4)上的 NSNotificationCenter 具有以下行为:

如果您为确切的特定通知多次注册,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 调用,我将收到重复通知到我的视图控制器。

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

只是把它放在那里,以防其他人遇到这样的事情。

于 2013-04-21T02:18:49.603 回答
2

你应该并且总是清理你的观察者。
最简单的方法是: [[NSNotificationCenter defaultCenter] removeObserver:self]
viewDidLoad 不是添加观察者的好地方,因为这个函数可能会被多次调用,当 viewDidUnload 被触发时会发生这种情况。将 addObservers 放入 viewWillAppear 并将 removeObservers 放入 viewWillDisappear 的好地方。

于 2013-01-24T07:31:48.347 回答
0

正如您自己所说, NSNotificationCenter 不检查重复项,这对某些人来说可能很烦人,但在考虑其背后的完整系统时才有意义。

相同的逻辑适用于向某些对象添加目标,但通常对这些对象进行关键识别。

感谢您的洞察力,以及对 SEO 友好的良好警告 :)

于 2012-12-29T10:43:32.590 回答