0

This code results in an "invalid selector" error when the button I create is pressed. Where is the test function fetched from?

Main.m

mainScreen = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 768, 1024)];
[self.view addSubview:mainScreen];

TaskButtons *tB = [[TaskButtons alloc] init];
[mainScreen addSubview:[tB TaskStart]]; 

TaskButtons.m

- (UIButton*)TaskStart {
   CGRect buttonFrame = CGRectMake(500, 206, 400, 35);
   UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
   button.frame = buttonFrame;
   [button setTitle:@"Task Button" forState:UIControlStateNormal];
   button.backgroundColor = [UIColor clearColor];
   button.titleLabel.textAlignment = UITextAlignmentLeft;
   button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
   [button setTitleColor:[UIColor darkGrayColor] forState:UIControlStateNormal];
   [button addTarget:self action:@selector(test) forControlEvents:UIControlEventTouchUpInside];
   return button;
 }

- (void)test{
   NSLog(@"test line");
}

It seems that the test function isn't being called. Doesn't setting the button's target to self here mean it should look in the TaskButtons class for the function called test?

jscs
  • 63,694
  • 13
  • 151
  • 195
Ray Y
  • 1,261
  • 3
  • 16
  • 24
  • 2
    Please include the text of the invalid selector message. This will tell you which object the action message is really being sent to. – jrturton Nov 28 '11 at 17:33
  • I found out it is ARC trying to release my instantiated object too soon before the selector can be called. If I import TaskButtons.m into Main.h and TaskButtons *tB; in the interface. Then retain it in a property by @property (nonatomic, retain) TaskButtons *tB; I can keep the instantiated class around long enough to call the selector without ARC releasing my class too soon. – Ray Y Nov 28 '11 at 17:42
  • 1
    `test` is a method, not a function. – Macmade Nov 28 '11 at 17:45
  • This may be secondary, but UIControl selectors are in the form `@selector(method:)`, where the signature would look like `-(void)method:(id)sender`. Omitting the argument may result in unexpected behavior. – Jumhyn Nov 28 '11 at 21:38

2 Answers2

0

The problem is ARC is releasing the instantiated object too soon. So to solve this I would need to retain it longer.

Main.h

#import "TaskButtons.m"
@interface ViewController : UIViewController {
     TaskButtons *tB;
}

@property (nonatomic, retain) TaskButtons *tB;
Ray Y
  • 1,261
  • 3
  • 16
  • 24
0
[button addTarget:self action:@selector(test:) forControlEvents:UIControlEventTouchUpInside];

- (void)test:(id)sender{
NSLog(@"test line");
}

Syntax problem :) In your code replace these lines.

Naveen Thunga
  • 3,675
  • 2
  • 24
  • 31