NSNotificationCenter part 2: Implementing the observer pattern with notifications

This article is the second part of a series about NSNotificationCenter. The previous part covers the basics of receiving and sending notifications.

If you ever tried implementing the observer pattern in Objective-C you might have noticed the need of using a non-retaining collection for the observers to avoid retain cycles, among other caveats.

Instead of writing your own custom observer implementation, a much leaner approach is using NSNotificationCenter. We could of course use it directly, but we would lose the strong typing expected from the observer pattern. Here’s how to implement this popular pattern with NSNotificationCenter at its core.

Typed observer

First, we define the observer protocol. In this example we will observe a custom audio player (HPEAudioPlayer):

Each observer method will correspond to a notification, hence the single notification parameter. The observer will not need to know the notification name; this will be an implementation detail.

Then, we add methods in our observable class to add and remove observers.

In the implementation of our observable class we define constants for the notification names:

Adding and removing the observer is reduced to calling NSNotificationCenter with the appropriate filters:

Finally, notifying the observers is as simple as posting the corresponding notification. NSNotificationCenter will take care of the rest.

Typed parameters with categories

When using the observer pattern one would expect the notification methods to have well-defined and typed parameters. Unfortunately, in the example above we’re using a generic NSNotification as our single parameter. What is the object? What is inside userInfo? We can do slightly better by using a category on NSNotification to explicitly answer these questions.

For our audio player example, we could have the following category:

By using these category methods the observer does not need to worry about casting the object property and doesn’t need to know the keys of the userInfo dictionary, or use it at all. Note that the additional properties are readonly, as NSNotification objects are expected to be immutable.

The category approach has still a problem, which is that the observer must know which category methods are available for each notification method (e.g., hpe_endTime is not defined for audioPlayerDidStartPlackback:). This can be solved by subclassing NSNotification.

Typed parameters with subclassing

Subclassing NSNotification allows us to provide a fully typed observer, including parameters, by giving each notification method its own notification subclass. Our observer protocol becomes:

As indicated in part 1, NSNotification is a class cluster that throws an exception if init is called. The implementation of its subclasses requires a few lines of boilerplate code:

Again, note that the properties are readonly to keep the notifications immutable.

The subclassing approach allows us to provide a fully typed observer at the expense of creating one class per method and dealing with NSNotification subclassing quirks. If strict typing is not required, the category approach is also valid as long as the parameters of each method are properly documented.

Further reading

3 thoughts on “NSNotificationCenter part 2: Implementing the observer pattern with notifications

  1. Pingback: NSNotificationCenter part 1: Receiving and sending notifications | Hermes Pique

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">