January 19, 2009

iPhone: send and receive events/notifications

Objective-C has a really friendly and useful event system that allows your objects to talk to each other without any knowledge of the other objects. Events are called Notifications in Objective-C, and are routed through a system-wide object called NSNotificationCenter. You don't need to import this object - it's always available to every class.

Here's the syntax for dispatching an event/notification with an ID of "EventName":

[[NSNotificationCenter defaultCenter] postNotificationName:"EventName" object:self];

It also sends along "self", which is a reference to the dispatching object. You could replace "self" with a reference to another object that may contain more relevant data to the event being dispatched.

To respond to this event, you need to set up a listener:

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

Our object, "self" is now ready to receive this event. It must have a function called "listenerFunction", but this name is up to you. Note that setting "nil" as the object lets us respond to any object in the application that sends out a notification called "EventName". Alternatively, we can listen to only one object that will send this event, by replacing "nil" with a reference to the object.

Finally, you need a function that actually does something when the event/notification is received. See below:

- (void)listenerFunction:(NSNotification *)notification
{
MyDispactherObject *incomingObject = [notification object];
NSLog(@"EVENT RECEIVED");
}

If we don't need to do anything with the object that was sent with the event, we can ignore the first line in the function.

[UPDATE]: Thanks to CC in the comment section for correcting my example and reminding us that we want to clean up after ourselves and remove event listeners before things are properly garbage collected. Here's the syntax for removing the listener we added above (replace "nil" with the object reference if you were listening to a specific object):

[[NSNotificationCenter defaultCenter] removeObserver:self name:@"EventName" object:nil];


Finally, here's Apple's official Notification documentation for further reading:
http://developer.apple.com/documentation/Cocoa/Conceptual/Notifications/Introduction/introNotifications.html

3 comments:

  1. You are my new hero. You just answered two of the questions I had. Thanks for posting these.

    ReplyDelete
  2. By the way, there's a (small) bug in your example code. You need an "@" symbol before "EventName" or else you'll get errors.

    Also, you might want to mention how to stop listening:

    [[NSNotificationCenter defaultCenter] removeObserver:self];

    An object listener needs to remove itself from the table before it is deallocated.

    ReplyDelete
  3. ooh thanks for the correction. updating now :)

    ReplyDelete