UIViewController throwing unrecognized selector exception on prepareForSegue
Asked Answered
H

8

7

I'm trying to follow along the Stanford CS193p iOS programing lectures. One of the demo programs, called "Happiness" creates two UIViewControllers, a "PsychViewController" and a "HappinessViewController." It segues from the PsychViewController to the HappinessViewController using a target action method.

The following code keeps throwing this exception: "-[UIViewController setHappiness:]: unrecognized selector sent to instance"

Here's the offending code:

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"ShowDiagnosis"]) {
    [segue.destinationViewController setHappiness:7];
}
}

I have searched this site and others, and the usually when this error comes up, it is because the generic UIViewController has not been correctly set to the specific view controller object used in the program, in this case the "HappinessViewController." But I have set the generic UIViewController to be a HappinessViewController using the identity inspector in IB, and I am still getting the exception. I am tearing my hair out, if anyone could help it would be much appreciated.

Hesperides answered 1/11, 2012 at 3:15 Comment(0)
H
7

I figured out the problem. Although I had correctly specified that the relevant UIViewController was a HappinessViewController, the linker, was for some reason, not linking to the correct files. The fix was to go to double click on the .xcodeproj file inside Xcode, then go to Build Phases and manually add the files under "Compile Sources."

Hesperides answered 1/11, 2012 at 20:20 Comment(0)
Y
19

Let's look at the exception:

-[UIViewController setHappiness:]: unrecognized selector sent to instance

This tells you two things about the message that was unrecognized. It tells you the selector, setHappiness:. It also tells you the actual, runtime class of the receiver, UIViewController.

Of course, UIViewController has no method named setHappiness:. That's why you got the exception.

You wrote a subclass of UIViewController called HappinessViewController which does have a setHappiness: method (or a read/write property named happiness, which generates the method). And you intended for the receiver (the destination view controller) to be an instance of that subclass (HappinessViewController).

But the exception is telling you that the destination view controller is just a plain UIViewController. So even though you think you did, you probably did not set the view controller's custom class in the storyboard. Maybe you set the custom class of some other view controller, but you didn't set the class of this segue's destination.

You need to set the destination view controller's custom class in the Identity Inspector, like this:

set custom class in identity inspector

Yurikoyursa answered 1/11, 2012 at 3:32 Comment(2)
Unfortunately, that doesn't work. I had already set the view controller to be a HappinessViewController, but no luck. I also tried deleting the existing view controller putting a new one in, wiring it up and following the directions in your post and animation. Still no luck. For some reason, I can't get it recognize that the destination view controller is a HappinessViewController. Please let me know if you have any other thoughts. Still tearing my hair out.Hesperides
Great explanation. I felt like I was schooled... in a good way.Hauteur
H
7

I figured out the problem. Although I had correctly specified that the relevant UIViewController was a HappinessViewController, the linker, was for some reason, not linking to the correct files. The fix was to go to double click on the .xcodeproj file inside Xcode, then go to Build Phases and manually add the files under "Compile Sources."

Hesperides answered 1/11, 2012 at 20:20 Comment(0)
D
4

For me changing the class of the view controller in the story board worked.enter image description here

Duke answered 16/7, 2014 at 8:6 Comment(0)
D
1

Try like this:

HappinessViewController *controller = segue.destinationViewController;
[controller setHappiness:7];
Derangement answered 1/11, 2012 at 3:19 Comment(1)
This is a good idea, casting the UIVewController as a HappinessViewController. But it did not work. I still get the same unrecognized selector exception. Please let me know if you have any other thoughts. Soon to be bald from tearing my hair out...Hesperides
R
0

I had the same problem today and it was because my custom class was in a library. The library itself was being linked in build phases, but that in itself was not enough to pull in the class. So finally I solved it by add the following line to my AppDelegate.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
   [ CustomClass class ];
}

This forces the linker to pull in the class. Otherwise simply linking in the library may not be enough to pull in the class unless it is referenced somewhere in the application.

Ress answered 9/12, 2014 at 6:23 Comment(0)
D
0

I tried adding a Cast and it worked for me, I had the same problem:

 FirstViewController *detailViewController =
    (FirstViewController *)[segue destinationViewController];
Delubrum answered 12/4, 2015 at 19:0 Comment(1)
OP commented another answer that casting didn't help.Thermo
J
0

Check which prepareForSegue is triggering. My problem was that 2 segues were triggering, in the current viewController and in the incoming viewController. The solution, and always a good practice is to check segues identifiers.

- (void)prepareForSegue:(UIStoryboardSegue*)segue sender:(id)sender
{
     if ([segue.identifier isEqualToString:@"segueIdentifier"]) {
    }
}
Jegar answered 21/9, 2017 at 0:57 Comment(0)
S
-1

Cast before assigning

HappinessViewController *controller = (HappinessViewController *)segue.destinationViewController;
[controller setHappiness:7];

Make sure in your storyboard, HappinessViewController is set as the class of you VC

Sapienza answered 13/5, 2013 at 19:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.