Issue while calling NSNotificationCenter

338 views Asked by At

I want to call a method from another class via NSNotificationCenter.Everything is working fine.

The problem is my method called up two times.

ViewController.m

 - (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(removeAllSubViews:) name:@"getTheRequest" object:nil];

// Do any additional setup after loading the view, typically from a nib.
}

- (void)removeAllSubViews:(NSNotification *)notification
{
NSLog(@"%@",notification.object);

NSLog(@"Print");


}

ViewController2.m

- (void)viewDidLoad {
[super viewDidLoad];
 [[NSNotificationCenter defaultCenter] postNotificationName:@"getTheRequest" object:@"mySite"];
// Do any additional setup after loading the view.
}

When I run, I get this in console:

Console output

Why my method is called up two times ?

Edit

When I use this code in ViewController2.m it works fine. But Why?? **

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

There are 4 answers

3
Kirit Modi On

You have to remove observer after use of it inside the method.

- (void)removeAllSubViews:(NSNotification *)notification
{
 [[NSNotificationCenter defaultCenter] removeObserver("getTheRequest")]

NSLog(@"%@",notification.object);

NSLog(@"Print");

}
0
Mike On

I've seen this before when I had a retain cycle in my view controller, so every time a instance of this view controller was created, it was added as an NSNotificationCenter observer, but because of the retain cycle when the view controller was dismissed, it was never actually deallocated/released from memory, so technically it was still an observer.

You might want to try to add the following to your view controller:

- (void)dealloc {
    NSLog(@"Dealloc called.");

    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

This should remove your view controller as an observer when it is dismissed, if there is no retain cycle, and if there is the NSLog will never be called - which is indicative of a larger memory-related issue, where what you're seeing is just a side-effect.

0
Daniel Rinser On

You are probably seeing multiple calls to that method, because you register the observer multiple times (e.g. you have navigated to that view controller before), but did not remove it again at the appropriate places. Anyways, viewDidLoad is very likely not the ideal place to register an observer. A common place to do this is the designated initializer, and removing it again in dealloc.

As a side note (and without seeing enough code for a very informed opinion), your use case ("remove all subviews") does not sound like notifications are a good approach. Have you considered using delegation?

0
0yeoj On

It is possible that there is a double NSNotificationCenter registration.

I think you have declared another:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(removeAllSubViews:) name:@"getTheRequest" object:nil];

somewhere.. trying finding the other one..

And just a tip, when you register for NSNoticationCenter try removing first the observer like:

// removes the observer
[[NSNotificationCenter defaultCenter] removeObserver:YourObserver name:YourName object:YourObject];

followed by:

// register
[[NSNotificationCenter defaultCenter] addObserver:YourObserver selector:YourSelector name:YourName object:YourObject];

Just to remove the existing one, if any..