Tuesday 10 February 2009

NSNotifications: a broadcasting mechanism

Notifications are a strong mechanism to broadcast messages to multiple recipients , and also to loosely couple objects.

Typical examples are :

- GUI elements that want to notify other GUI elements about an event. (for example : a window that closes can notify all controls on the window about the close).
- In a MVC application, the model can notify about changes in his internal state (internal variables that are changing).

To be able to use a notifications we need 2 things : a central broadcast component and a way to register an intrest for notifications (and a way to post notifications).

Apple in his Cocoa framework offers the following implementation :

1. The central broadcast component

[NSNotificationCenter defaultCenter]

The NSNotificationCenter is the class that implements the central broadcast component, and by sending the message defaultCenter you get a singleton instance of it.
Note that each application can only have one nsnotificationcenter.

2. Register for an interest in a notification

[[NSNotificationCenter defaultCenter]
addObserver:myInstance

selector:@selector(doSomethingWhenNotified:)
name:@"someName"
object:nil ] ;

With the above statement you register with the notification center the following :
when somebody (a class in your application) sends a notification with name "someName", then to the object myInstance the message doSomethingWhenNotified: will be sent.

Important note : the message doSomethingWhenNotified: must have the following signature :
- (void) doSomethingWhenNotified: (NSNotification *) notification

(= your notification message must accepts one argument of type NSNotification *).

Note 2 : This method is best called in the awakeFromNib method. Because then you are sure that your window is properly initialized.

3. Posting a notification

To post a notification you do the following :

[[NSNotificationCenter defaultCenter] postNotificationName:@"someName" object: nil ]

Note: this is for example used in a method which changes a variable.

General note : in both cases you see the "object: nil", instead of nil you can use any object, but then the notificationcenter will only post the notifications for that particular object.

6 comments:

  1. Thanks for the tutorial. Helped me a lot! :)

    Regards
    Kartik Thapar

    ReplyDelete
  2. Hey thanks a lot . . . nice tutorial . It saved my lot of time searching what exactly notification does . Simple and helping tutorial . Keep it up !!

    :)

    Bharat

    ReplyDelete
  3. Hi, thanks for this tutorial.

    I've got a question... does it need not to remove the nsnotification object?

    ReplyDelete
  4. Hi Jayr,

    It all depends, my objects are usually in an NSAutoRelease pool, so it gets released automatically

    ReplyDelete
  5. Thanks for the writeup - concise and helpful.

    As for jayr parro 's question, wouldn't it be "good practice" to couple removeObserver calls with each addObserver calls once an object no longer needs to listen to notifications? When an object is autoreleased, does this removeObserver get called automatically?

    Thanks

    ReplyDelete
  6. @Charles, indeed , indeed you should somewhere call the removeObserver. I usually put all that in the dealloc method (together with all other memory cleanup).
    To be honest I don't think removeObserver is called automatically when an autorelease pool is released.
    I'll experiment a little bit with that to see what the behaviour really is.

    ReplyDelete