NSNotfication Not Working, But Looks Right? :: Find That Bug!

NSNotification and NSNotificationCenter are two super useful classes in Cocoa. Like so many things in Cocoa, they are well thought out. But notifications can be a source of hard to track down bugs. You will find them, because often they prevent your application from doing things that should be seen visually in the interface. The question is, how quickly will you find them…?

This code (from the Hillegass book, Cocoa Programming For Mac OS X, 2nd ed.) shows an NSDocument subclass implemented and registering each instance of itself as an observer of particular notifications:

 
@implementation MyDocument

- (id)init
{
    self = [super init];
    if (self) {
		employees = [[NSMutableArray alloc] init];
		NSNotificationCenter *nc;
		nc = [NSNotificationCenter defaultCenter];
		[nc addObserver:self
			   selector:@selector(handleColorChange:)
				   name:@"JJColorChange"
				 object:nil];
    }
    return self;
}

…

And here we have another object’s method that sends the notification our document class is interested in observing and acting on:

 
...
- (IBAction)changeBackgroundColor:(id)sender
{
	NSColor *color = [sender color];
	NSData *colorAsData;
	colorAsData = [NSKeyedArchiver archivedDataWithRootObject:color];
	NSUserDefaults *defaults;
	defaults = [NSUserDefaults standardUserDefaults];
	[defaults setObject:colorAsData
				 forKey:JJTableBgColorKey];

	NSNotificationCenter *nc;
	nc = [NSNotificationCenter defaultCenter];
	[nc postNotificationName:@"JJColorChanged" object:self];
}
…

 

I did take out all NSLog lines to make it a bit easier to follow the code itself. There is nothing special or spectacular or unusual about any of it. This is just an example of where naming things can be a big deal. NSNotifications can also indeed be a bit like the infamous GOTO statements. Let’s face it, eventually object orientation can lead to its own brand of spaghetti code, too. As convenient and useful as they are, they are a bit fragile, since the names are important, generally hard-coded, and I haven’t yet seen or come across a nice category/protocol style way of simply declaring an object to be an observer of some set of notifications. Even with it, you still need to act explicitly on a notification, so it does require some care to make sure things are spelled right.

Did you find it yet? I hope so. With a lot more code surrounding things, it can be a bit tougher to locate, but the difference is between:


    @"JJColorChange"

and:


    @"JJColorChanged"

Only one letter. Conceptually, they’re also very close. Observing both the action (noun) and the completed action (regular past tense verb). Either one could be a valid, short announcement! Both could be part of a larger English sentence respectively, and still express the same thing.

Perhaps this is why Cocoa engineers seem to use “Did” instead. A lot easier to spot the difference between:


    @"JJColorDidChange"

and:


    @"JJColorChange"

Why? It is a subtle effect of the way the human brain actually reads and recognizes words. We do not read each letter. Our brain scans text for the general shape of whole words and phrases. That’s the developmental difference between somebody who can read, and somebody who is
still
learning
to
read
and
reads
like
this.

Thus, if you have a choice you want to choose the added word in the middle that changes the shape of the whole thing. This same effect occurs with CamelCase or the_underscores_in_ruby. But look at these examples as well:


    @"CamelCase"
    @"CamelCased"

    @"CamelCase"
    @"CamelDidCase"
    @"CamelWillCase"
    @"CamelByCase"

Notice now, how the last bunch make a lot more sense and are easier to distinguish visually. What some people initially believe is verbose and hard to read is made with some thought in mind. So now you see classic Steve Jobs/Apple thinking in the design even of Cocoa. (ok, ok, NeXT, but even then, same bunch of brilliant people and same culture)

0 comments ↓

There are no comments yet...Kick things off by filling out the form below.

Leave a Comment