Previous Entry Add to Memories Tell a Friend Next Entry
Always use notification name globals, not literal strings!
userpic
[info]chanson
What's wrong with this code?
- (void)registerForNotificationsFromTask:(NSTask *)task ( {
    [[NSNotificationCenter defaultCenter]
        addObserver:self
           selector:@selector(taskDidTerminateNotification:)
               name:@"NSTaskDidTerminateNotification"
             object:task];
}
If you didn't notice anything wrong, look again.

What's bad about this is that it's passing a string literal instead of a global variable for the notification name. The code should really look like this:
- (void)registerForNotificationsFromTask:(NSTask *)task ( {
    [[NSNotificationCenter defaultCenter]
        addObserver:self
           selector:@selector(taskDidTerminateNotification:)
               name:NSTaskDidTerminateNotification
             object:task];
}
Isn't that better? (Among other things, Xcode will offer to complete the NSTaskDidTerminateNotification global variable for you — unlike the contents of a string literal.)

This is a bug that often results from copying & pasting from documentation into code. "I need this notification, it needs to be a string, so I'll just put @"" around it." The type of a notification name is, in fact, NSString but you don't have to pass a string literal for that. Instead, pass the global variable that exists for each notification name and you're guaranteed that the right thing will happen.

If you're creating and using your own notifications, be sure to follow the Cocoa pattern and create your own global variables containing the notification name. Otherwise you're at the mercy of typos within string literals.

Update: Sanjay Samani helpfully pointed out that by constant string I meant string literal. Thanks, Sanjay! I've updated my post with this correction. (Not sure where my memory was…)

(Leave a comment)

"Constant String"

(Anonymous)

2008-07-01 09:40 am (UTC)

In case this confuses C die hards, another phrase for "constant string" is "string literal" and I am so glad that someone told me about the dangers of string literals early in my career.

Of course avoiding them is not just good practice with Notifications, but throughout your programming. One exception I use myself is for accessing Key/Value pairs (e.g. -valueForKey:@"name") as I found it more readable with syntax colouring to use string literals. Though thinking about it, the correct solution would be to change the syntax colouring of global & project constants.

(Sanjay Samani, DayTime Software)

Underlying values != variable name

(Anonymous)

2008-07-03 01:37 am (UTC)

There are cases where the underlying value is not the same as the global variable name, NSPasteboard type's are a good example of this,and more subtle ones like NSNibOwner is @"NSOwner". It shouldn't matter, like you say, always use the global.

(Leave a comment)