Search code examples
objective-ccocoanotificationsevent-bubbling

NSNotification concept - what piece of code goes where?


Part of me thinks I understand the NSNotification concept. It's a centralized broadcast system with string based notifications. Post on one side, observe on one or multiple other sides and act accordingly. Another part of me though, the part that has to write the code, gets confused every time I need a notification. What piece of code goes into which header/implementation, what files actually do the observing and how do I keep it from becoming a mess? Time to straighten it out, will you help me verify these assumptions? I'm fairly confident up to number 4, but number 5 hits the confusion jackpot.


  1. NSNotifications are created with help from the [NSNotification defaultCenter], one does not alloc/init a NSNotification. Correct?
  2. The object performing the postNofification feat always passes self into the posting code: [[NSNotificationCenter defaultCenter] postNotificationName:@"note name" object:self]. Correct?
  3. Event bubbling exists in other languages, but not in Objective-C with NSNotification. You don't pass along notifications, you make the notification name specific enough for the global broadcast. Correct?
  4. If you still want to pass along a notification posted by object A, you observe it in B, handle it and post a new, more specific notification for object C to observe. Eg. @"MenuItemTapped" from A to B, and @"NavigateTo" from B to C. Correct?
  5. The name of a notification is a NSString. Because both the poster and the observer want to avoid typos, we store the NSString constant in a [extern const|define|class method|none of the above]. Could you help me pick one?
    • One attempt was to create something like a NotificationNames.h file, which would contain all the extern NSString *const NOTE_NAME declarations. Yet that undermines the portability of a notification.
    • Another attempt was to subclass NSNotification (with an XCode template to keep the creation fast), but because this concept is taken from subclassing the Event-class in AS3, it seemed very un-objective-c-ish. There's also the weirdness that you can't call [super init] on a NSNotification, so things started to get out of hand.
    • My troubles with this one arise from the cumbersome #import statements. How to minimize typo's, yet keep the constants/defines portable?

Solution

  • You've mostly got it. Your numbers 1-3 are generally correct.

    • You shouldn't ever need to alloc your own NSNotification object.
    • You generally pass "self" as the "object" of the notification as you say, but you could also pass something else in if you are notifying "on behalf of" something else, conceptually. But that would be less common case.
    • Notifications aren't the same as "events" in the UI. Cocoa does have events; they are mouse/keyboard/touch events, and they do "bubble" up the "responder chain" through the UI objects. Notifications are a totally independent mechanism that is not tied to UI, and it is used for generally global broadcast among otherwise decoupled/independent objects. It's more akin to having multiple delegates for an object.
    • Yes, you should define the name of the notification somewhere that everyone who uses it can see. In Cocoa itself, this is usually a public header with a declaration like extern NSString *const UIKeyboardDidShowNotification. In some private implementation file is the definition.

    A special note regarding your #4 above. Think of notifications as notifications, not as instructions. They usually capture state changes or broadly interesting events. "MenuItemTapped" is a reasonable thing to notify about, but "NavigateTo" usually isn't, because the implication is that you're telling some specific object to navigate somewhere. If that's the case, that object should probably be a delegate (or should be a property) of the thing that wants the navigation, and you should cause it to happen directly. This isn't a requirement, of course, and you can use the mechanism for whatever you want. But the Cocoa design patterns generally don't use notifications for "telling objects what to do", only for "telling whoever cares what will/did happen". Make sense?

    Finally, specifically re: your examples in #4-- those sound like genuine UI events, and seem like the whole thing could be handled via delegation, unless there's some reason why those objects need to be so decoupled.