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

Posted January 16, 2009 by Quinn McHenry in 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.


About Quinn McHenry

Quinn was one of the original co-founders of Tech-Recipes. He is currently crafting iOS applications as a senior developer at Small Planet Digital in Brooklyn, New York.
View more articles by Quinn McHenry

The Conversation

Follow the reactions below and share your own thoughts.