I have next code:
@implementation SplashViewVC
- (void)viewDidLoad
{
[super viewDidLoad];
self.splashView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"Default.png"]];
self.activityIndicator.originY = 355.f;
[[NSNotificationCenter defaultCenter] addObserverForName:NCDownloadComplete object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *n){
NSInteger errorCode = [n.userInfo[@"errorCode"] integerValue];
[self.activityIndicator stopAnimating];
if (errorCode == ERROR_CODE_NO_CONNECTION) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Some problem with server" delegate:self cancelButtonTitle:@"try again" otherButtonTitles:nil];
[alertView show];
} else if (errorCode == 0) {
[self dismissViewControllerAnimated:YES completion:nil];
}
}];
[self downloadData];
}
- (void)downloadData
{
[self.activityIndicator startAnimating];
[[Server sharedServer] getMovieData];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
[self downloadData];
}
- (void)viewDidDisappear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super viewDidDisappear:animated];
}
@end
So I put breakpoints in begin of viewDidLoad
method, in viewDidDisappear
. When I launch app that first go to viewDidload
, after downloading it is go to viewDidDisappear
.
But during my app I again download data and post notification: NSDownloadComplete
. And in this VC it is work, but I removed later using:
[[NSNotificationCenter defaultCenter] removeObserver:self]
This VC use viewDidLoad
once in the beginning & can not again addObserver.
What is wrong?
EDIT
I try put addObserver method to viewWillAppear
or viewWillDisappear
- no results.
I add NSLog(@"addObserver");
before
[[NSNotificationCenter defaultCenter] addObserverForName...
in viewDidLoad
and write
- (void)viewDidDisappear:(BOOL)animated
{
NSLog(@"removeObserver");
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super viewDidDisappear:animated];
}
In log I see:
2013-06-10 14:32:05.646 myApp[9390:c07] addObserver
2013-06-10 14:32:06.780 myApp[9390:c07] removeObserver
What wrong?
EDIT 2 you can see that observer must be removed but it again run block in addObserver method
What e1985 is trying to expose is that your
addObserver
andremoveObserver
calls are not properly balanced.viewDidLoad
is called only once after the VC initialization, butviewDidDisappear
is called each time the view controller is moved off screen.To resolve your issue you must balance your
addObserver
andremoveObserver
calls, either by making them inviewDidLoad
and the other indealloc
, or - as e1985 suggested - inviewDidAppear:
andviewDidDisappear:
.EDIT: Ok, so your problem comes from the fact that you are using
addObserverForName:object:queue:usingBlock:
which do not registerself
as observer (asaddObserver:selector:name:object:
would do if you passself
as first argument).So in your case,
[[NSNotificationCenter defaultCenter] removeObserver:self];
does nothing becauseself
is not an observer. You should instead callremoveObserver:
on the return value ofaddObserverForName:object:queue:usingBlock:
, as shown in the doc:So your code should looks something like:
The pattern you are using is not correct. You should add the observer in
viewDidAppear:
and remove it inviewDidDisappear:
.Apart from add/remove observer calls not properly being balanced, at noted in the other answers, there is another problem.
Your code to remove the observer is wrong. For a block-based observer, the return value of
addObserver
must be given as argument toremoveObserver
. So you should add a propertyto the class. Then you add the observer with
and remove it with