Aug 24, 2010

NSViewController or: How I Learned to Stop Worrying and Love the… ah screw it.

NSViewController sucks. Really. It’s just awful.

Let’s compare UIKit’s UIViewController with AppKit’s NSViewController:

UIViewController:

  • loads nib
  • tracks view lifecycle
  • tracks view appearances
  • handles low memory notifications
  • watches for orientation changes

NSViewController:

  • loads nib
  • oh yeah, nothing else

And just in case NSViewController didn’t seem lame enough, the one thing that it does—load nibs—isn’t the hard part; that other stuff is the hard part. Loading nibs is a simple matter of a couple method calls to NSBundle or NSNib. We, non-AppKit developers, can do that easily ourselves.

So last week when I was working on a new Mac project, I decided to fix this thing once and for all. Warning: what follows involves the swizzling of methods. If you’re faint of heart or hate runtime funsies, turn back now.

I really hoped to do it without swizzling, I really did. But I’m pretty sure that’s not possible. The only class that knows anything about view lifecycle or appearances is NSView himself. I could create a subclass of NSView but that becomes a pain in the ass whenever I want to use a subclass of NSView. Like if I wanted my view controller to control an NSTableView, I would have to create an NSTableView subclass. Or if I wanted it to control an NSScrollView… or an NSBrowser… or… or…

We’re suddenly talking about a lot of subclasses with a lot of duplicated code, not to mention the added hassle. So the only option I was left with was swizzling methods on NSView. And so that’s what I did.

All that said, I present, for your enjoyment, JAViewController and his NSView extension buddies. Mac OS X 10.6-only because it uses associated objects (though that could, conceivably, be changed if you needed 10.5 support), and it requires garbage collection (though it would be pretty trivial to make it behave without it):

http://github.com/joshaber/JAViewController

About

Mostly I work on GitHub for Mac. Mostly.

twitter / github