Question

This is a strange accumulation bug that's somehow pushing my VCs onto the Nav VC multiple times.

I have a UINavigationController with rootViewController set to CWLandingVC (lvc).

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    CWLandingVC *lvc = [[CWLandingVC alloc] init];
    UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:lvc];
...
}

On the lvc, the user logs in and when my APIClient class gets a successful server response it posts a notification:

     NSNotification* notification = [NSNotification notificationWithName:@"sessionArrived" object:self];
     NSLog(@"APIClient Posting notification for sessionArrived");
     [[NSNotificationCenter defaultCenter] postNotification:notification];

The lvc listens for this and sends this selector accordingly:

NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserver:self
           selector:@selector(toPagebookWorkspace)
               name:@"sessionArrived"
             object:client];
...
- (void)toPagebookWorkspace {
NSLog(@"lvc Calling toPagebookWorkspace for session %@.  Opening PagebookWorkspace view.", [self sessionId]);
CWWorkspaceVCViewController *wvc = [[CWWorkspaceVCViewController alloc] init];
[[self navigationController] pushViewController:wvc animated:YES];
}

The bug arises when the user logs in, successfully does pushViewController:wvc, logs back out to lvc, and logs right back in. When they do this, the notification is posted once more – which I verify with NSLog(@"Posting notification for sessionArrived"); – but the selector toPagebookWorkspace is called twice. If I repeat the bug, the selector is called 3 times, and so on. So each time I repro the bug, more and more wvc's get pushed on top of each other in the UINavigationController.

Perhaps these logs can help illuminate the strange accumulating sequence I'm seeing. For each APIClient notification post, I get an increasing number of pushViewController:wvc, rather than just 1 push.

     Logging in...
     APIClient Posting notifcation for sessionArrived
     lvc Calling toPagebookWorkspace for session lvcke2.  Opening PagebookWorkspace view.
     Pressed back on nav bar, calling viewWillDisappear


     Logging in...
     APIClient Posting notifcation for sessionArrived
     lvc Calling toPagebookWorkspace for session lvcke2.  Opening PagebookWorkspace view.
     lvc Calling toPagebookWorkspace for session lvcke2.  Opening PagebookWorkspace view.
     nested push animation can result in corrupted navigation bar
     Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.
     Unbalanced calls to begin/end appearance transitions for <CWWorkspaceVCViewController: 0x8067410>.
     Pressed back on nav bar, calling viewWillDisappear
     Pressed back on nav bar, calling viewWillDisappear


     Logging in...
     APIClient Posting notifcation for sessionArrived
     lvc Calling toPagebookWorkspace for session lvcke2.  Opening PagebookWorkspace view.
     lvc Calling toPagebookWorkspace for session lvcke2.  Opening PagebookWorkspace view.
     nested push animation can result in corrupted navigation bar
     lvc Calling toPagebookWorkspace for session lvcke2.  Opening PagebookWorkspace view.
     nested push animation can result in corrupted navigation bar
     Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.
     Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.
     Unbalanced calls to begin/end appearance transitions for <CWWorkspaceVCViewController: 0x8068330>.
     Pressed back on nav bar, calling viewWillDisappear
     Pressed back on nav bar, calling viewWillDisappear
     Pressed back on nav bar, calling viewWillDisappear


     Logging in...
     APIClient Posting notifcation for sessionArrived
     lvc Calling toPagebookWorkspace for session lvcke2.  Opening PagebookWorkspace view.
     lvc Calling toPagebookWorkspace for session lvcke2.  Opening PagebookWorkspace view.
     nested push animation can result in corrupted navigation bar
     lvc Calling toPagebookWorkspace for session lvcke2.  Opening PagebookWorkspace view.
     nested push animation can result in corrupted navigation bar
     lvc Calling toPagebookWorkspace for session lvcke2.  Opening PagebookWorkspace view.
     nested push animation can result in corrupted navigation bar
     Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.
     Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.
     Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.
     Unbalanced calls to begin/end appearance transitions for <CWWorkspaceVCViewController: 0x7257930>.
     Pressed back on nav bar, calling viewWillDisappear
     Pressed back on nav bar, calling viewWillDisappear
     Pressed back on nav bar, calling viewWillDisappear
     Pressed back on nav bar, calling viewWillDisappear

If you have any idea what's up, thanks so much for your help in advance.

Was it helpful?

Solution

This is the expected behaviour of NSNotificationCenter: any object can add multiple observers, even for the same name, object, and selector. If you don't want to have your selector called multiple times (and it doesn't seem like you do), do the inverse of addObserver: by calling:

[[NSNotificationCenter defaultCenter] removeObserver:self name:@"sessionArrived" object:client];

(Important note: do NOT call [[NSNotificationCenter defaultCenter] removeObserver:self], as it will result in your object losing observation for all notifications its superclass(es) may have registered for. See this link for more information on why this is a bug.)

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