Although I haven’t posted much, if anything, on Cocoa programming I thought I’d post a bit more over the next few months. I’ve been coding in Cocoa for quite a few years now and it is, by far, the most productive application coding environment I’ve ever worked in. Unfortunately, the scope of Cocoa is huge and, if it wasn’t for other Cocoa programmers posting hints, notes and tips, I’d still be scratching my head about topics like drag-and-drop weirdness with NSTokenField bindings (more on this in a later post).
So this is to try to repay the favor to other coders who’ve struggled with the same things I have. And where better to start than one of the uglier problems that many programmers run in to; subclassing class clusters. The Cocoa designers, in their infinite wisdom, decided to make a few of the core Cocoa classes based on a class cluster and not concrete. This makes them awkward to try to subclass as you have to work out all of the primitive methods and provide support for them in the subclass.
Most folks end up giving up in disgust and wrapping things like NSMutableDictionary. However, once in a while, you really, really, really need to subclass it. In my case, I wanted a basic class that I could use in RapidAlbum that would call a delegate when an object in the dictionary was added or changed (so that I could flag a page export). However, I really wanted a dictionary interface as I wanted to be able to leverage all the existing NSDictionary methods (like dictionaryFromDictionary:) as the whole point is to avoid writing more code.
The trick here is to catch
removeObject:forKey: and add a delegate call. Note that if you could easily register a wildcard key-value observer for a container class that tracked all key/object changes in the class, then this would be unnecessary. That’s an expletive-laden rant for another day.
There’s a few pointers out there as to how to subclass NSMutableDictionary but nothing that really covers all of it. So, without further ado, here’s the approach I took.