iOS / iPhone用户警告重复的NSNotification观察

时间:2010-06-18 20:22:20

标签: iphone ios macos nsnotificationcenter nsnotifications

这不是一个问题,而是警告他人保存一段时间。

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调用,我将向视图控制器发送重复通知。

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

如果有其他人遇到这样的事情,请把它放在那里。

3 个答案:

答案 0 :(得分:4)

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调用,我将向视图控制器发送重复通知。

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

如果有其他人遇到这样的事情,请把它放在那里。

答案 1 :(得分:2)

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

答案 2 :(得分:0)

正如你自己所说的那样,NSNotificationCenter不会检查重复项,这对某些人来说可能很烦人,但在确认它背后的完整系统时是有意义的。

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

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