Patroclus
Patroclus

Reputation: 1232

Remove a C++ observer from NSNotification?

In C++, it is not hard to add an Observer for a notification. But the problem is that how could I remove an Observer.

[[NSNotificationCenter defaultCenter] addObserverForName:@"SENTENCE_FOUND" object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {

So normally we use

[[NSNotificationCenter defaultCenter] removeObserver:self name:@"SENTENCE_FOUND" object:nil];

to remove an observer.

But since C++ doesn't have self and when I use this, I got the following error

Cannot initialize a parameter of type 'id _Nonnull' with an rvalue of type 'DialogSystem *'

So how could I remove a C++ class observer? Or it is impossible?

Upvotes: 0

Views: 178

Answers (1)

Willeke
Willeke

Reputation: 15598

Copied from the documentation of -[NSNotificationCenter addObserverForName:object:queue:usingBlock:]:

Return Value

An opaque object to act as the observer.

Discussion

If a given notification triggers more than one observer block, the blocks may all be executed concurrently with respect to one another (but on their given queue or on the current thread).

The following example shows how you can register to receive locale change notifications.

NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
self.localeChangeObserver = [center addObserverForName:NSCurrentLocaleDidChangeNotification object:nil
    queue:mainQueue usingBlock:^(NSNotification *note) { 
        NSLog(@"The user's locale changed to: %@", [[NSLocale currentLocale] localeIdentifier]);
    }];

To unregister observations, you pass the object returned by this method to removeObserver:. You must invoke removeObserver: or removeObserver:name:object: before any object specified by addObserverForName:object:queue:usingBlock: is deallocated.

NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center removeObserver:self.localeChangeObserver];

Edit: Copied from the same page:

Another common pattern is to create a one-time notification by removing the observer from within the observation block, as in the following example.

NSNotificationCenter * __weak center = [NSNotificationCenter defaultCenter];
id __block token = [center addObserverForName:@"OneTimeNotification"
                                       object:nil
                                        queue:[NSOperationQueue mainQueue]
                                   usingBlock:^(NSNotification *note) {
                                       NSLog(@"Received the notification!");
                                       [center removeObserver:token];
                                   }];

Upvotes: 2

Related Questions