iPhone SDK: Solve [UINavigationController pushViewController:] unrecognized selector sent to instance

Contributor Icon Contributed by qmchenry Date Icon January 16, 2009  
Tag Icon Tagged: Apple iPhone

I adore coding to the iPhone SDK. It’s the most joyful coding I’ve done in the quarter century (gasp!) I’ve spent coding various computer systems. It’s a combination of Objective-C (elegant) and Cocoa (beautiful). There is one exception I keep getting and just infrequently enough that I forget why I get it. I thought someone might benefit from this because it’s an easy trap to fall into.

The exception in question:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[UINavigationController pushViewController:]: unrecognized selector sent to instance 0x5255c0'

If you use the Navigation-Based Application template when creating a new project, you’ll get a set of project files that gets you a good bit of the way towards a functional application. In fact, you can hit build and go and the app will compile, run, and show you a pretty table view. You will probably then add code to make the table view display stuff in the cells, testing along the way, and it’ll work. At some point, you may want to make touches on the cells open a new view. The template provides an example method “didSelectRowAtIndexPath” shown here:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here. Create and push another view controller.
// AnotherViewController *anotherViewController = [[AnotherViewController alloc] initWithNibName:@"AnotherView" bundle:nil];
// [self.navigationController pushViewController:anotherViewController];
// [anotherViewController release];
}

The method itself is not commented out, but all of the instructions within it are. These commented lines provide a clue as to what should happen. The line

[self.navigationController pushViewController:anotherViewController];

is the key to both the operation of this method and the cause of the error. It pushes a new view controller on the navigation stack and displays it, exactly what you want it to do. However, if you uncomment this line and adjust it to use the new view controller you’ve created, you’ll get a warning when you build it: “warning: ‘UINavigationController’ may not respond to -pushViewController:’” But, well, this is a warning, not an error. Pshaw. Run it, though, and you’ll get the error shown above, and unrecognized selector sent to an instance.

If what you’ve read so far sounds familiar, the likely solution is simple. The line above from the Apple-provided template is wrong. There actually isn’t a message signature for UINaigationController called -pushViewController: but there is one called -pushViewController: animated: — Oops! Sorry Apple! We still love you, though. Very easy to fix, but if it happens after a long day of coding, it can cause undue frustration. The corrected line should look something like:

[self.navigationController pushViewController:anotherViewController animated:YES];

Rebuild and this error will be solved! If this was your problem. If it wasn’t, then don’t despair. Decrypting exception messages is part of the fun part of the lifestyle of coderdom. An “unrecognized selector” is still going to refer to the message you are sending “to instance,” some object that you’ve created. The exception even tells us which class of the object that is receiving the weird message (UINavigationController in this case) and the message that was sent (pushViewController:). In this case, the compiler knew that there was something icky about the message being sent, but it may not always be able to determine this, so you can’t rely on it. However, you should be able to search your code for the message reported in the exception from the console log. Make sure everything is proper in this line checking in the documentation for the exact nature of the call.

Previous recipe | Next recipe |
 
  • Shaun Austin
    Cheers for this. I'm new to it all and I knew it must be something like that but even having looked at the Docs I'd missed the fact that I didn't have the "Animated" bit... wood for trees etc.

    Thanks again.
  • And I was struggling to find the solution thinking I was doing something wrong in the initialization of the view controller to be pushed.
    Thank you, you saved me from a crisis of nerves :)
  • guilhem
    good tip. it helped.
  • David
    My thanks - I was staring at this for at least 10 minutes. Of course if I had have just highlighted "pushViewController" and Option + double-clicked to bring it up in the Class Reference, I would have seen the signature was wrong.
  • Ashwini
    Hey,
    That was quite helpful.
    Saved lot of time.
    Thank you.
  • Bitrace
    Great thanks for this! You just saved me hours of frustration 80)
  • Tomasz
    Many many thanks - I was about ready to tear my hair out...
  • Jason
    Thanks. That one was starting to get to me.
blog comments powered by Disqus