Search code examples
iosuiviewcontrolleruitabbarcontrollerobserver-patternnsnotificationcenter

View controller is not removing Notification Center observer


I have this viewDidLoad code:

- (void)viewDidLoad
{
   [super viewDidLoad];

   [[NSNotificationCenter defaultCenter] removeObserver:self];

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

This view controller is one of an UITabBarController. Every time I go to its tab, viewDidLoad is called, but it seems that [[NSNotificationCenter defaultCenter] removeObserver:self]; does nothing and "messageReceived" is registered each time the method is called.

This code snippet from another class that notifies:

[[NSNotificationCenter defaultCenter] postNotificationName:@"messageReceived"
                                                            object:nil
                                                          userInfo:nil];

is called only once but, if for example, I go 3 times to the tab of the view controller that is observing and the viewDidLoad is called 3 times, then its messageReceived: method is also called 3 times...

What could I be missing?


Solution

  • You probably want to hook the following:

    -(void)viewWillAppear:(BOOL)animated
    {
      [super viewWillAppear:animated];
      [[NSNotificationCenter defaultCenter] addObserver:self
                                                selector:@selector(messageReceived:)
                                                 name:@"messageReceived"
                                               object:nil];
    }
    
    -(void)viewWillDisappear:(BOOL)animated
    {
      [super viewWillDisappear:animated];
      [[NSNotificationCenter defaultCenter] removeObserver:self];
    }
    

    when you tap on your tab bar, a new instance of your UIViewController gets created, hence the viewDidLoad that gets called. When you call the removeObserver method from within viewDidLoad, you are asking to remove the newly created view controller from the observers, which at that point as never registered.

    -viewWillDisappear is called before your view controller is removed from the view hierarchy, so calling removeObserver from that method should do the trick.

    Good luck!