按钮的操作导致“无效选择器”崩溃——为啥?

Posted

技术标签:

【中文标题】按钮的操作导致“无效选择器”崩溃——为啥?【英文标题】:Button's action causes "invalid selector" crash -- why?按钮的操作导致“无效选择器”崩溃——为什么? 【发布时间】:2011-11-28 17:31:12 【问题描述】:

当按下我创建的按钮时,此代码会导致“无效选择器”错误。 test 函数是从哪里获取的?

Main.m

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

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

任务按钮.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");

似乎没有调用test 函数。在这里将按钮的target 设置为self 是否意味着它应该在TaskButtons 类中查找名为test 的函数?

【问题讨论】:

请包含无效选择器消息的文本。这将告诉您操作消息真正发送到哪个对象。 我发现 ARC 试图在选择器被调用之前过早地释放我的实例化对象。如果我将 TaskButtons.m 导入 Main.h 和 TaskButtons *tB;在界面中。然后通过@property (nonatomic, retain) TaskButtons *tB; 将其保留在一个属性中我可以将实例化的类保持足够长的时间来调用选择器,而 ARC 不会过早释放我的类。 test 是一个方法,而不是一个函数。 这可能是次要的,但 UIControl 选择器采用@selector(method:) 的形式,其中签名看起来像-(void)method:(id)sender。省略参数可能会导致意外行为。 【参考方案1】:

问题是 ARC 过早地释放实例化对象。所以要解决这个问题,我需要保留更长时间。

Main.h

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


@property (nonatomic, retain) TaskButtons *tB;

【讨论】:

【参考方案2】:
[button addTarget:self action:@selector(test:) forControlEvents:UIControlEventTouchUpInside];

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

语法问题 :) 在您的代码中替换这些行。

【讨论】:

以上是关于按钮的操作导致“无效选择器”崩溃——为啥?的主要内容,如果未能解决你的问题,请参考以下文章