NSNotificationCenter
is straightforward mechanism for implementing a clean
MVC architecture, but it is also somewhat cumbersome and error-prone. The receiving object
has to register itself with the notification center for the
particular notification, specified by a string. It also has to implement a method for
handling the notification, and the registration and the method have to match. The string
used has to be coordinated with the senders of the notification, with no checking whatsoever. The
compiler doesn't help with the manual bookkeeping and there is no indication in the interface
that the class receives notifications.Let's fix this with Notification Protocols.
Notification Protocols: Usage
First, let's define a protocol for our notification. We want aModelDidChange
notification. We also want common message to be sent to our objects, in this case the message -modelDidChange:
.
@protocol ModelDidChange <MPWNotificationProtocol>
-(void)modelDidChange:(NSNotifiction*)notification;
@end
This protocol must contain a single message and conform to
MPWNotificationProtocol
,
which indicates that this is a notification protocol. This way, we define that a particular
notification always maps to one specific message, but this is common and should probably be
considered a best-practice.Second, a class wishing to adopt this notification must conform to the protocol:
@interface NotifiedView:NSView <ModelDidChange>
@end
NotifiedView
must implement -(void)modelDidChange:(NSNotificaiton*)notification;
, but fortunately the compiler will tell us if we
forget to do this, because of the protocol conformance declaration. Finally, and this is the
part that can't really be checked, the object must call [self installProtocolNotifications]
somewhere in its initializer. It's probably best to do this in a common superclass.
Then, just use the PROTOCOL_NOTIFY
macro to send the notification. The macro
takes the name of the protocol as its argument. It uses the @protocol
compiler
directive to turn that into the protocol and then uses the protocol's name for the
notification.
PROTOCOL_NOTIFY(ModelDidChange,changedUri);
That's it! Your
NotifiedView
will now get the -modelDidChange:
message.
The string is hidden behind the use of @protocol
, meaning the compiler helps a bit in checking
that we are sending the right notification (there are far fewer protocols than strings). The
protocol also helps us keep the mapping from notification to message straight, mostly by automating
it away. It also allows us to declare conformance to the notification statically, both for readers
and for checking that we actually implement the method.
Notification Protocols: Implementation
The implementation is quite simple: the-installProtocolNotifications
method iterates over all the
protocols an object's class conforms to. For the ones that conform to MPWNotificationProtocol
it
registers itself with NSotificationCenter
to be sent the message in the protocol.The implementation is part of MPWFoundation.
No comments:
Post a Comment