views:

210

answers:

1

Basically, I have a view1 which at some point, calls view2 (via presentModalViewController:animated:). When a certain button in view2 is pressed, view2 is calls a notification method in view1 and immediately afterward is dismissed. The notification method pops up an alert.

The notification method works fine and is called appropriately. The problem is, every time view1 is created (only one view1 should exist at a time), I presumably get another NSNotification being created because if I go from view0 (the menu) to view1, then back and forth a few times, I get a series of the same alert message, one after another, from the notification method as many times as I opened a view1.

Here is my code, please tell me what I'm doing wrong:

View1.m

-(void) viewDidLoad {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(showAlert:) name:@"alert" object:nil];
}

-(void) showAlert:(NSNotification*)notification {
// (I've also tried to swap the removeObserver method from dealloc
// to here, but it still fails to remove the observer.)
// < UIAlertView code to pop up a message here. >
}

-(void) dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}

View2.m

-(IBAction) buttonWasTapped {
[[NSNotificationCenter defaultCenter] postNotificationName:@"alert" object:nil];
[self dismissModalViewControllerAnimated:YES];
}

-(void) dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
A: 

Calling -dealloc doesn't automatically happen after the view controller is dismissed — there can still be some "life" left in the view controller's lifetime. In that timeframe, that view controller is still subscribed for that notification.

If you remove the observer in -viewWillDisappear: or -viewDidDisappear:, this will have a more immediate effect:

- (void) viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"alert" object:nil];
}
Alex Reynolds
First, thanks for the response. If I use the code you provided, my notification method is never called! But when I put it back to dealloc, the notification method comes back... but still with the same problem :(
Derek
Could this be because the viewWillDisappear is called when I use presentModalViewController in the same view? I'm not sure what the problem is.
Derek
Is this method being called from within a `UIView` or a `UIViewController` instance?
Alex Reynolds
The notification method? It's being called from another UIViewController which is displayed on-screen by [self presentModalViewController:view2 animated:YES]
Derek
Is `-viewWillDisappear:` being called from within a `UIViewController` subclass or within a `UIView` subclass? You must only override `-viewWillDisappear:` from within a `UIViewController`. Also make sure you add the `name` and `object` of the notification you are removing from observation, which the code in your question does not include (and which may explain why it is not working).
Alex Reynolds
Ah... yes, view1 (the view that registers the notification and contains the notification method) inherits from UIViewController. I also did change the method to removeObserver:name:object: and I get no warnings or errors, but still putting that method call in viewWillDisappear: method stops the notification method from ever being called. Only when I comment it out will the notification method execute. I am registering the notification in voidDidLoad, could that be causing a problem? Honestly, I'm stumped!
Derek
I don't fully understand how your view controllers are being pushed. Perhaps register the notification observer in `-viewWillAppear:` and the corresponding unregistration in `-viewWillDisappear:`.
Alex Reynolds
I tried in -viewWillAppear: and it works as before, and as before, adding the removal code to the -viewWillDisappear: causes the notification method to never be called. Thanks for all your help Alex, you don't need to answer any further -- I'll just try a technique to try to accomplish this.
Derek