NSDistributedNotificationCenter observer spontaneously stop observing

I've setup an observer in my process using the following:

[[NSDistributedNotificationCenter defaultCenter] addObserver:__self
                                                    selector:@selector(methodA:)
                                                        name:@"NotificationName"
                                                      object:nil
                                          suspensionBehavior:NSNotificationSuspensionBehaviorDeliverImmediately];


I have another process that would broadcast a notification using the following:

[[NSDistributedNotificationCenter defaultCenter] postNotificationName:@"NotificationName"
                                                               object:nil
                                                             userInfo:userInfo
                                                              options:NSNotificationPostToAllSessions];


Normally, the observer receives the broadcasted notifications without problems. However, on very very rare occurancies, I have seen a working observer stop responding to the broadcasted notifications. In order to verify my findings, I wrote another utility program to monitor the broadcast of distributed nofications. In the instances where the observer stop observing, the utility program registers broadcast notifications that were sent from the Distributed Notificaiton Center.


Furthermore, when the observer stops observing, I know that runloop is not stuck. As I have a timer on the main run loop that fires on regular intervals, and I do see the timer being fired while the observer had stop observing.


Are there any known reason why a previously working observer would stop receiving distributed notification?

How can I programatically check that the observer is broken?

And if I can detect that the observer is broken, would removing and creating a new observer solves the issue?


This issue has been very diffcult to troubleshoot, as I cannot determine the reason why the notification observer suddenly stop working.

The first thing to do is to eliminate memory management issues as the cause. According to the documentation, the -[NSDistributedNotificationCenter addObserver: …] method does not retain the observer, so you have to make sure it doesn't deallocate before it's been explicitly removed.


I don't know what "__self" represent in your code fragment, but I would look for ways that it might get accidentally freed earlier than you expect.

I verified that the observer is not being deallocated. The observer (__self) is just a weak reference of self in this case.


self is an object that never goes away during the run time of the process.

You can try working around the problem by re-registering the observer, but that's just papering over whatever the real issue is.


Before you do anything else drastic to debug this, I would suggest you try switching to the "addObserverForName:object:queue:usingBlock:" method. It has different semantics (it returns an opaque object that you must keep alive for as long as you want the observation to last), but it should protect the observation from accidents.


If that doesn't help, it might be worth trying to recreate the problem in a minimal app, especially if you can increase the traffic so that the failure happens more often. Other than that, I don't have any clever ideas about how to debug this.

Thank you for your suggestions @QuinceyMorris.


Unfortunately, I won't be able to use "addObserverForName:object:queue:usingBlock" as I'm working between different processes which require the use of NSDistributedNotificationCenter rather than NSNotificationCenter.

NSDistributedNotificationCenter is a subclass of NSNotificationCenter, so it should inherit that method. Whether or not it works in the subclass is a different matter (plus, I don't know how you would specify the suspension behavior).


Unfortunately, it's hard to guess whether this (mis)behavior comes from a bug, or some environmental condition. Is there something you can try, to make it fail more often

I've been trying to find out how to make it fail more often. I'm very sure that it's not the issue of the notification observer object being dealloc earlier than expected, as the notification observer object is the main process object on the main thread. The object would only get deallocated when the process shutsdown.


I'm hoping to see if other have encounter similar problem where the Notification Center stop passing notification to a specific observer.


Thank you @QuinceyMorris for your suggest thus far.

Sorry I can't be of more help.


Always remember when debugging hard problem like this to widen your scope of search. For example, one reason the observations might stop is that something called "removeObserver" on that object (or some API with that effect). It might not have been intended, perhaps "removeObserver" was called with a pointer to the wrong object.


If you really come to the conclusion that the framework behavior is supect, you can always try using a TSI on your developer account to get an Apple engineer to look at the problem. This may be a more productive approach than spending many days or weeks guessing at potential causes.

I’m not sure what’s going on here but I wanted to point out that the various notification centres have a really useful implementation of

debugDescription
. Obviously you can access this from LLDB:
(lldb) po [[NSDistributedNotificationCenter defaultCenter] debugDescription]
<_NSLocalNotificationCenter:0x6040000c09a0>
Name, Object, Observer, Options
… lots of good stuff …

but you can also access it programmatically. Thus you could add a debugging option to your app to help with this investigation.

Also, it wasn’t clear what platform you’re working on here. I suspect macOS, but please confirm.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Yes, this is for macOS.


I'll add the call to -debugDescription in my code and try to reproduce the problem again. Hopefully, it will be able to tell me something useful.


Thank you for your suggestion Quinn!

NSDistributedNotificationCenter observer spontaneously stop observing
 
 
Q