Question

I have 2 observers registered. One of them is in appDelegate and the other is in myViewController. When I am in myViewController, I just expect to get two notifications, one from appDelegate which executes some method globally, the other one from myViewController which executes some other method. But, only the one in appDelegate gets called. If I remove the observer in appDelegate, the observer in myViewController gets called. Actually, I can just use the observer method in appDelegate and find out the current view controller and execute the code of the method in myViewController. But, I just don't wanna mess appDelegate. The same code for both of them but I remove the observer in myViewController when viewWillDisappear() method gets called. Any ideas? Thanks.

appDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [[NSNotificationCenter defaultCenter] addObserver:self   
                                             selector:@selector(someMethod:)
                                                 name:@"someName"
                                               object:nil];
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    [[NSNotificationCenter defaultCenter] postNotificationName:@"someName"
                                                        object:nil
                                                      userInfo:someUserInfo];
}

- (void)someMethod:(NSNotification *)notification
{
    // gets called
}

myViewController

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

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

- (void)viewWillDisappear:(BOOL)animated
{
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:@"someName"
                                                  object:nil];

    [super viewWillDisappear:animated];
}

- (void)someMethod:(NSNotification *)notification
{
    // not called
}
Was it helpful?

Solution

In the code below you're posting before observing

 (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [[NSNotificationCenter defaultCenter] postNotificationName:@"someName"
                                                        object:nil
                                                      userInfo:someUserInfo];

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

* Original * Plenty of possible issues here:

one the notification Name could be spelt wrong = @"someName" - If this is going to be observe red from other classes, think about creating an

in a .h (that both classes import) include

extern NSString * const XXXSomeNameForSomeNotification; 

in the corresponding .m

NSString * const XXXSomeNameForSomeNotification = @"someName";

That's one way to ensure they're all observing/posting the right notification

If that's not your issue then try adding observing the notification from the viewDidLoad or another method that's called prior to viewDidAppear as it could be that it's not observing you notification when it's actually posted. Add break points to observe this.

OTHER TIPS

Looks like, Your notification is posted before view is loaded. See adding some logs.

OR try this -

    double delayInSeconds = 2.0;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){

        [[NSNotificationCenter defaultCenter] postNotificationName:@"someName"
                                                            object:nil
                                                          userInfo:someUserInfo];
    });

I think as per you posted code the reason is

- (void)viewWillDisappear:(BOOL)animated
{

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

[super viewWillDisappear:animated];

}

The method above will remove the notification observing if the current view is not on screen.

Also you may want to move the

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

to

- (void) dealloc
{
       [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:@"someName"
                                                  object:nil];
}

that way you only stop observing the notification when you remove the view controller form memory. You may want to check in the method that's called if you're on screen.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top