将另一个选择器/名称对添加到NSNotificationCenter中的现有观察者

时间:2011-11-08 03:12:16

标签: iphone objective-c cocoa-touch nsnotifications nsnotificationcenter

我不确定它的确切原因(除了下面描述的歧义),但我已经读过不应该将多个观察者添加到同一对象的NSNotificationCenter中。但是,我想在通知中心的同一个对象中添加第二个选择器/名称对。

我添加了第一个如下:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(method1:) 
                                             name:@"method1Notification"
                                           object:nil];

选项1:

添加第二个(如下所示)似乎会再次向通知中心添加“self”。

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(method2:) 
                                             name:@"method2Notification"
                                           object:nil];

这可以吗?或者,如果有必要,是否可以简单地将另一个选择器/名称对添加到默认通知中心的“self”条目中?


选项2 :(伪代码)

[[[NSNotificationCenter defaultCenter] mySelfObserver]
                        addSelector:@selector(method2:) 
                               name:@"method2Notification"
                             object:nil];

歧义:

无论哪种方式,如果是第二次添加,在dealloc:中,它可能需要作为观察者两次被删除?

[[NSNotificationCenter defaultCenter] removeObserver:self];
// ... REMOVE IT AGAIN IF OBSERVER ADDED TWICE TO NOTIFICATION CENTER?

2 个答案:

答案 0 :(得分:1)

您发布的所有内容(“选项1”)都可以。见the docs

  

removeObserver:

     

从接收者的调度表中删除指定给定观察者的所有条目。

     

- (void)removeObserver:(id)notificationObserver

您只需拨打removeObserver:一次;如果您只想删除特定通知的单个遵守,则会有单独的removeObserver:name:object:方法。

答案 1 :(得分:0)

我觉得你有点困惑。只要通知或对象不同,任意次数添加给定观察者都是完美的。

如果为单个通知/对象组合多次添加观察者,您将收到多个通知 - 每次添加观察者时,您的通知方法将被调用一次。这通常是不可取的,我认为这是你见过的建议。

你也只需要为任何观察者召唤一次removeObserver:,无论观察多少东西。

- (void)registerForNotifications
{
    NSNotificationCenter * noteCenter = [NSNotificationCenter defaultCenter];
    [noteCenter addObserver:self
                   selector:@selector(keyboardWasShown:)
                       name:UIKeyboardDidShowNotification 
                     object:nil];

    [noteCenter addObserver:self
                   selector:@selector(keyboardWillBeHidden:)
                       name:UIKeyboardWillHideNotification 
                     object:nil];
    // Totally fine up to this point; this object is observing two different
    // notifications.
    // Now, add two different observations for the same notification, but
    // with _different_ objects:
    [noteCenter addObserver:self
                   selector:@selector(fluffyHasReproduced:)
                       name:RabbitsHaveReproducedNotification
                     object:MyRabbitFluffy];
    [noteCenter addObserver:self
                   selector:@selector(luckyHasReproduced:)
                       name:RabbitsHaveReproducedNotification
                     object:MyRabbitLucky];
    // This is fine; the appropriate rabbit notification method will only be
    // called when the corresponding rabbit reproduces.
    // However...
    // This will make luckyHasReproduced: be called _twice_ whenever
    // MyRabbitLucky posts RabbitsHaveReproducedNotification
    [noteCenter addObserver:self
                   selector:@selector(luckyHasReproduced:)
                       name:RabbitsHaveReproducedNotification
                     object:MyRabbitLucky];
    // Further,
    // this is probably not what you want. otherRabbitsHaveReproduced: is
    // going to be called whenever either Fluffy or Lucky post their
    // notifications, too. The nil object acts as a wildcard.
    [noteCenter addObserver:self
                   selector:@selector(otherRabbitsHaveReproduced:) 
                       name:RabbitsHaveReproducedNotification 
                     object:nil];

}

稍后,适当时(viewWillDisappear:viewDidUnload:用于视图控制器,具体取决于通知的性质; dealloc用于其他对象):

- (void) unregisterForNotifications {
    // Clear out _all_ observations that this object was making
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}