NSNotificationCenter trapping and tracing all NSNotifications

Viewed 11428

For some better understanding on what happens “under the hood”, I would love to do a complete trace of any notifications happening within my application.

Naïve as I am, the first thing I tried was registering like this:

Somewhere in my app:

{
    [...]
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(traceNotifications:) name:nil object:nil];
    [...]
}

- (void)traceNotifications:(NSNotification *)notification
{
    NSLog(@"received notification %@", [notification name]);
}

I do actually get a number of notifications that way. But at some point the application does crash. The stack trace shows it is crashing with EXC_BAD_ACCESS in realizeClass, which from my experience does indicate that something gets called after its deallocation. My observing object however still is alive, its deallocator has not been called (yet).

Next thing I tried was setting a breakpoint towards -[NSNotificationCenter postNotification:] and then run po {NSNotification *}($ebp+16) inside the gdb-console whenever my breakpoint is trapped. That did reveal a few notifications but not all that I am expecting/hoping for. For example, my application does handle orientation-changes properly but I do not see any notifications being trapped when reorienting the device (in the simulator).

What am I missing? Is there a way (e.g. a tool) for reliably observing a NSNotificationCenter?

Thanks for any hint.

5 Answers

For debugging purposes, I find that a breakpoint is actually better than adding code to the project. However, @Till's solution didn't seem to work for me. I found another solution online, and tweaked it a bit.

Symbolic Breakpoint

  • Symbol: -[NSNotificationCenter postNotificationName:object:userInfo:]
  • Condition: ((NSRange)[$arg3 rangeOfString:@"^(_|NS|UI)" options:1024]).length == 0
  • Action: Debugger Command po $arg3
  • Automatically continue after evaluating actions

Notes:

  • The condition is preventing any notifications that begin with _, NS, or UI from being displayed.
  • 1024 refers to NSRegularExpressionSearch, which doesn't seem to be available for that breakpoint.
  • I use .length == 0 instead of .location == NSNotFound because NSNotFound seems to evaluate to a different value (-1 or (NSUInteger)18446744073709551615) than the returned value in this breakpoint (9223372036854775807).

@Till solution in Swift 5.0 & Xcode 11:

CFNotificationCenterAddObserver(
    CFNotificationCenterGetLocalCenter(),
    nil,
    { (notificationCenter, _, notificationName, _, dictionary) in
        print(notificationName)
        print(dictionary)
}, nil, nil, .deliverImmediately)
Related