Error w/ Silver Chllnge: unrecognized selector sent to insta

#1

Hi there,

Well this chapter and challenges are especially hard to grip for a newbie!

My app launches fine, but crashes when I click on the Segmented Control.

Here’s my code in BNRHpynosisViewController.m

[code]@interface BNRHypnosisViewController ()

@property (nonatomic, strong) BNRHypnosisView *backgroundView;

@end

@implementation BNRHypnosisViewController

-(instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
//Set the tab bar item’s title
self.tabBarItem.title = @“Hypnotize”;

    //Create a UIImage from a file
    UIImage *i = [UIImage imageNamed:@"Hypno.jpg"];
    //Put that image on the tab bar item
    self.tabBarItem.image = i;
}

return self;

}

-(void)loadView
{
//Create a view
self.backgroundView = [[BNRHypnosisView alloc] init];

//create segmented control
NSArray *segmArray = [NSArray arrayWithObjects:@"Red", @"Green", @"Blue", nil];
UISegmentedControl *segmentedControl = [[UISegmentedControl alloc]initWithItems:segmArray];
segmentedControl.frame = CGRectMake(35, 400, 250, 20);
segmentedControl.selectedSegmentIndex = 1;
segmentedControl.backgroundColor = [UIColor whiteColor];
[segmentedControl addTarget:self.backgroundView
                     action:@selector(chooseColor:)
           forControlEvents:UIControlEventValueChanged];

//Set this as *THE* view of this view controller
self.view = self.backgroundView;

[self.view addSubview:segmentedControl];

}

//When a view controller finishes loading its view, it is sent the message viewDidLoad. We can change it’s behaviour, for example by adding a log when the view has loaded
-(void)viewDidLoad
{
//Always call the super implementation of viewDidLoad
[super viewDidLoad];

NSLog(@"Hypno controller loaded its view");

}

-(void)chooseColor:(UISegmentedControl *)segment
{

if (segment.selectedSegmentIndex == 0) {
    self.backgroundView.circleColor = [UIColor redColor];
    
} else if (segment.selectedSegmentIndex == 1) {
    self.backgroundView.circleColor = [UIColor greenColor];
   
} else if (segment.selectedSegmentIndex == 2) {
    self.backgroundView.circleColor = [UIColor blueColor];
    
}

}

@end
[/code]

I couldn’t do this myself for the moment and tried to copy a solution from this forum, thus I am not certain I fully understand everything that’s going on here at the moment.

Here the log when the app crashes:

[quote]2014-08-18 19:43:42.066 HypnoNerd[16899:60b] -[BNRHypnosisView chooseColor:]: unrecognized selector sent to instance 0x8d524d0
2014-08-18 19:43:42.128 HypnoNerd[16899:60b] *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘-[BNRHypnosisView chooseColor:]: unrecognized selector sent to instance 0x8d524d0’
*** First throw call stack:
(
0 CoreFoundation 0x017f11e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x015708e5 objc_exception_throw + 44
2 CoreFoundation 0x0188e243 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275
3 CoreFoundation 0x017e150b forwarding + 1019
4 CoreFoundation 0x017e10ee _CF_forwarding_prep_0 + 14
5 libobjc.A.dylib 0x0158282b -[NSObject performSelector:withObject:] + 70
6 UIKit 0x002323b9 -[UIApplication sendAction:to:from:forEvent:] + 108
7 UIKit 0x00232345 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 61
8 UIKit 0x00333bd1 -[UIControl sendAction:to:forEvent:] + 66
9 UIKit 0x00333fc6 -[UIControl _sendActionsForEvents:withEvent:] + 577
10 UIKit 0x00333c06 -[UIControl sendActionsForControlEvents:] + 48
11 UIKit 0x003a2222 -[UISegmentedControl _setSelectedSegmentIndex:notify:animate:] + 598
12 UIKit 0x003a4573 -[UISegmentedControl touchesEnded:withEvent:] + 175
13 UIKit 0x00271ddd -[UIWindow _sendTouchesForEvent:] + 852
14 UIKit 0x002729d1 -[UIWindow sendEvent:] + 1117
15 UIKit 0x002445f2 -[UIApplication sendEvent:] + 242
16 UIKit 0x0022e353 _UIApplicationHandleEventQueue + 11455
17 CoreFoundation 0x0177a77f CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 15
18 CoreFoundation 0x0177a10b __CFRunLoopDoSources0 + 235
19 CoreFoundation 0x017971ae __CFRunLoopRun + 910
20 CoreFoundation 0x017969d3 CFRunLoopRunSpecific + 467
21 CoreFoundation 0x017967eb CFRunLoopRunInMode + 123
22 GraphicsServices 0x037e55ee GSEventRunModal + 192
23 GraphicsServices 0x037e542b GSEventRun + 104
24 UIKit 0x00230f9b UIApplicationMain + 1225
25 HypnoNerd 0x000034cd main + 141
26 libdyld.dylib 0x01e38701 start + 1
27 ??? 0x00000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
[/quote]

Any help would be greatly appreciated since I have absolutely no idea what’s going wrong here.

Thanks a lot in advance.

NC

#2

Well, I figured it out a few minutes after my post. :unamused:

The chooseColor action should not be in the View Controller but in the HypnosisView implementation.

My bad.

:arrow_right:

#3

I didn’t have the same code, but actually had the same error, and couldn’t find out why I was wrong.

The problem with your solution to add the code in HypnosisView is that it is not consistant with the UISegmentedControl and the chooseColor instance method being controllers.

To make myself clearer, you created two files:
-HypnosisView.m which gives you circles which can change color when you tap on the screen.
-HypnosisViewController.m which implements this view and gives you controls to the view. So in this file, you should find the tabs AND the UISegmentedControl AND the chooseColor method going along with the UISegmentedControl. Why ? Because you could create another ViewController which doesn’t need any UISegmentedControl neither chooseColor method, therefore their place is not in the HypnosisView.

So I don’t know why you had this error, but you can check out this topic to give you a good solution:
viewtopic.php?f=487&t=8467&p=29431#p29431