Debugging NSNotificationCenter

The debugDescription property has been around for quite awhile. Formally first appearing as a @property on NSObject in iOS 5 and macOS 10.8, it came across into Swift as a member of the CustomDebugStringConvertible protocol, and continues to be incredibly useful today.

But somehow it still manages to surprise me when I find a detailed custom implementation of the property, like the one I just discovered on NSNotificationCenter.

I don’t remember why I decided to try printing plain old NSNotificationCenter.defaultCenter in lldb, but I do remember being very surprised at the output. Rather than a plain object class-name-and-pointer pair like most things return, I found a long list of registered notification observers, complete with column headers:

(lldb) po NSNotificationCenter.defaultCenter
Name, Object, Observer, Options, 0x1055e61d0, 0x7f8df5300260, 1001, 0x1055e61d0, 0x7f8df5300260, 1001
UIAccessibilitySingleSystemColorChangedNotification, 0x1055e61d0, 0x106d19998, 1400, 0x1055e61d0, 0x7f8df5300260, 1001
UIAccessibilityReduceMotionStatusDidChangeNotification, 0x1055e61d0, 0x60800005bc00, 1400

This was way more helpful than I had dared hope for: every observer, the object it’s observing, and the name of the notification it’s waiting for. The amount of introspection here gives KVO’s observationInfo a run for its money.

The one downside is that I don’t have a great affinity for matching pointer addresses by sight, especially in the ocean of hexadecimal produced by sixty-plus lines of this output. What’s more, you’re practically guaranteed at least that much debugger spew, since the system frameworks register for quite a few notifications before your code even gets run.

I had to cut through the noise… and what better way to process an app’s debugging info than with another app?

A couple hours later, NotificationDebugger was born: a Mac app that takes a table of pointers and corresponding names, plus a text dump of NSNotificationCenter’s debugDescription, and produces a table of only the observations involving a named pointer.

Notification debugger screenshot

It’s definitely got my coder’s design sensibilities (i.e. no labels on anything, anywhere) – but it solved the problem I was facing, which is good enough for publication on GitHub. Find the source here, and let me know if this is useful to you!