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

Contributor Icon Contributed by qmchenry  
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.

 

17 Comments -


  1. Shaun Austin said on January 22, 2009

    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.

  2. Simone said on January 27, 2009

    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 :)

  3. guilhem said on January 29, 2009

    good tip. it helped.

  4. David said on February 2, 2009

    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.

  5. Ashwini said on April 23, 2009

    Hey,
    That was quite helpful.
    Saved lot of time.
    Thank you.

  6. Bitrace said on May 5, 2009

    Great thanks for this! You just saved me hours of frustration 80)

  7. Tomasz said on June 15, 2009

    Many many thanks – I was about ready to tear my hair out…

  8. Jason said on June 18, 2009

    Thanks. That one was starting to get to me.

  9. Anonymous said on February 9, 2010

    Thank you so much – I was getting very anxious there. Spent over an hour scratching my head! Naughty Apple indeed – the compiler should give the warning “Method not found” or something similar!

  10. Aaron said on March 2, 2010

    Big Thanks. Fixed the issue right up, you rock for posting this!

  11. Brian Wilson said on March 16, 2010

    apple compilers are crap – get used to it and use your natural senses.

  12. Anonymous said on March 26, 2010

    hello i am having same issue, i tried your solution but it didnt help me in my case..
    i am not getting exception but view is not getting changed..

    my piece of code is as below

    printf(“hi”);
    //Get the selected country
    NSString *selectedCountry = [listOfItems objectAtIndex:indexPath.row];

    //Initialize the detail view controller and display it.
    DetailViewController *aSecondView = [[DetailViewController alloc] initWithNibName:@”DetailView” bundle:nil];
    // aSecondView.selectedCountry = selectedCountry;
    [self.navigationController pushViewController:aSecondView];
    [aSecondView release];
    aSecondView = nil;
    printf(“bye..”);

    both hi and bye gets printed but view doesnt change..
    i have wasted 2 days around it ..
    plz help me out..

  13. Pradeep said on June 19, 2010

    Thank you so much.. I struggled with this issue for 2 days and finally got solved. Once again Thanks a lot..

  14. Lol said on August 8, 2010

    Your English sucks.

  15. Divanshu said on September 27, 2010

    absolutely spot on. cheers

  16. fank said on May 31, 2011

    Two years later… thank god you exist!

  17. Baskaraan said on August 12, 2011

    You saved my few hours/day…Thanks a lot

 

RSS feed for comments on this post. TrackBack URL

Leave a comment -