I have a UITabBarController
, which has 4 tabs. Each one of those tabs is a separate UIViewController
. I have objects on each one of those 4 VC\'s t
You must have implemented the NSNotificationCenter
's -addObserver:selector:name:object:
method in the -viewDidLoad
of every viewController
- (void)viewDidLoad
{
//...
[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(doSomething:)
name:@"TestNotification"
object:nil];
}
Instead of having this in -viewDidLoad
, move it within -viewWillAppear
and implement removeObserver:name:object:
in -viewWillDisappear
.
This way, only the viewController
that is currently on will respond to the notification.
- (void)viewWillAppear:(BOOL)animated
{
//...
[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(doSomething:)
name:@"TestNotification"
object:nil];
}
- (void)viewWillDisappear:(BOOL)animated
{
//...
[NSNotificationCenter defaultCenter] removeObserver:self
name:@"TestNotification"
object:nil];
}
- (void)doSomething:(NSNotification *)userInfo
{
//...
//if you push a viewController then the following is all you need
[self.navigationController pushViewController:vcSomething
animated:YES];
//however.... if you're instead presenting a viewController modally then
//you should implement "-removeObserver:name:object: in this method as well
//[NSNotificationCenter defaultCenter] removeObserver:self
// name:@"TestNotification"
// object:nil];
//[self presentViewController:vcSomething
// animated:YES
// completion:nil];
//OR... in the completion parameter as:
//[self presentViewController:vcSomething
// animated:YES
// completion:^{
// [NSNotificationCenter defaultCenter] removeObserver:self
// name:@"TestNotification"
// object:nil];
// }];
}
EDIT:
You (@Jonathan) commented:
I really appreciate your answer and it has helped me out a lot! I actually ran into one more scenario where this issue occur's and I'm not sure how to figure it out. Right now I have a VC that presents another VC modally. Each one has observers for the same NSNotification. Everything performs perfectly well when I'm in the modally presented VC, but once I dismiss that VC and return to the underlying one I have the same issue where the notification is being called multiple times. Do you have an idea for a solution in this case?
Now... regarding this...
FIRSTLY... NOTE:
-addObserver:selector:name:object:
will register the specified notification multiple times (means... same notification being registered for N times will call invoke the target selector N times)viewController
will NOT invoke the -viewWillDisappear:
of the ParentviewController
will still invoke -viewWillAppear:
of the ParentThis creates an imbalance in the logic and if not handled (as per the commented lines in the code example of the doSomething
method above), it results in the Parent registering for the notification multiple times (as it's -viewWillAppear:
method is called more often than not -viewWillDisappear:
)
also see: similar question
it should be called only once so that it never gets called again
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(methodName:) name:@"name" object:nil];
});