4

我不敢相信我偶然发现了这么简单的事情:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {

        UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        [button setTitle:@"Tap me" forState:UIControlStateNormal];
        [button addTarget:self action:@selector(test) forControlEvents:UIControlEventTouchUpInside];

        button.frame = CGRectMake(50, 50, 120, 60);
        [self.view addSubview:button];

    }
    return self;
}

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

当我按下按钮时它会崩溃,并出现unrecognized selector sent to instance错误。

有人知道我在这里做错了什么吗?

编辑 - 错误消息:

-[__NSCFString test]: unrecognized selector sent to instance 0x29ee30
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString test]: unrecognized selector sent to instance 0x29ee30'

编辑 - 它的呈现方式(ARC):

DemoViewController *demoVC = [[DemoViewController alloc] init];
    [self.window addSubview:demoVC.view];

    [self.window makeKeyAndVisible];
4

4 回答 4

10

如果您使用的是 ARC,那么 demoVC.view 将在函数结束后立即被重新调用,而不是像这样初始化

DemoViewController *demoVC = [[DemoViewController alloc] init];

在 demoVC 周围创建一个强大的属性并将其初始化为

self.demoVC = [[DemoViewController alloc] init];
于 2012-07-01T19:29:37.323 回答
3

您的错误消息表明(很可能)您的视图控制器在按下按钮之前被释放。(这表明消息正在发送到一个 NSString,它可能占用了视图控制器曾经所在的内存。)

追捕此问题的最简单方法是使用僵尸来确认这一点并确定您的对象被提前释放的原因。

编辑:根据您的演示代码,您应该制作一个实例变量以保留对您的视图控制器的引用。您可能还想移动按钮初始化代码viewDidLoad以避免将来出现其他问题。(或者只是把按钮挂在笔尖上!)

于 2012-07-01T19:24:01.047 回答
-1

添加任何带有代码的 UI 组件时,需要在 viewDidLoad 或 loadView(如果您不添加 xib 文件)中添加覆盖方法。

并且您还需要为发件人添加参数(这是推荐)

ex ) - (void)test:(id)sender

并像这样添加目标.... [button addTarget:self action:@selector(test:) forControlEvents:UIControlEventTouchUpInside]

于 2012-07-01T22:31:44.997 回答
-2

您可能会在代码中的某处为 NSString 调用“测试”方法。

于 2012-07-01T19:23:48.200 回答