【问题标题】:UIButton addTarget:action:forControlEvents: results in [NSObject doesNotRecognizeSelector:]UIButton addTarget:action:forControlEvents: 结果 [NSObject doesNotRecognizeSelector:]
【发布时间】:2011-03-04 01:05:16
【问题描述】:

我尝试了很多东西,仍然没有结果。

所以我在 UIViewController 的子类中以编程方式创建了以下按钮:

    rightButton = [UIButton buttonWithType:UIButtonTypeCustom];
    rightButton.frame = CGRectMake(0.0, 0.0, 110.0, 40.0);
    rightButton.titleLabel.font = [UIFont fontWithName:GAME_FONT_NAME_STRING size:20.0];
    [rightButton setTitle:@"MyTitle" forState:UIControlStateNormal];
    rightButton.backgroundColor = [UIColor clearColor];
    [rightButton setTitleColor:[UIColor greenColor] forState:UIControlStateNormal];
    [rightButton setTitleColor:[UIColor blackColor] forState:UIControlStateHighlighted];
    [rightButton setBackgroundImage:normalImage forState:UIControlStateNormal];
    [rightButton setBackgroundImage:highlightedImage forState:UIControlStateHighlighted];
    [rightButton addTarget:self action:@selector(myButton) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:rightButton];

选择器在哪里:

- (void)myButton;

我什么都试过了:

- (void)myButton;
- (void)myButton:(id)sender;
- (void)myButton:(id)sender forEvent:(UIEvent *)event;
- (IBAction)myButton;
- (IBAction)myButton:(id)sender;
- (IBAction)myButton:(id)sender forEvent:(UIEvent *)event;

当然还有相应的选择器:

[rightButton addTarget:self action:@selector(myButton) forControlEvents:UIControlEventTouchUpInside];
[rightButton addTarget:self action:@selector(myButton:) forControlEvents:UIControlEventTouchUpInside];
[rightButton addTarget:self action:@selector(myButton:forEvent:) forControlEvents:UIControlEventTouchUpInside];
[rightButton addTarget:self action:@selector(myButton) forControlEvents:UIControlEventTouchUpInside];
[rightButton addTarget:self action:@selector(myButton:) forControlEvents:UIControlEventTouchUpInside];
[rightButton addTarget:self action:@selector(myButton:forEvent:) forControlEvents:UIControlEventTouchUpInside];

结果总是一个未捕获的异常 - [NSObject doesNotRecognizeSelector:]。然而,程序通常的回溯是:

#0  0x92a6bedb in objc_msgSend ()
#1  0x03b0a430 in ?? ()
#2  0x00306b4e in -[UIControl sendAction:to:forEvent:] ()
#3  0x00308d6f in -[UIControl(Internal) _sendActionsForEvents:withEvent:] ()
#4  0x00307abb in -[UIControl touchesEnded:withEvent:] ()
#5  0x002bcddf in -[UIWindow _sendTouchesForEvent:] ()
#6  0x002a67c8 in -[UIApplication sendEvent:] ()
#7  0x002ad061 in _UIApplicationHandleEvent ()
#8  0x02498d59 in PurpleEventCallback ()
#9  0x01cabb80 in CFRunLoopRunSpecific ()
#10 0x01caac48 in CFRunLoopRunInMode ()
#11 0x02497615 in GSEventRunModal ()
#12 0x024976da in GSEventRun ()
#13 0x002adfaf in UIApplicationMain ()

那么那个按钮有什么问题呢?

PS:我使用的是 iPhone SDK 3.1.3


更新!

AppDelegate 中的以下代码(接口中没有声明):

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    UIButton *test = [[UIButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 100.0)];
    [test setTitle:@"Title" forState:UIControlStateNormal];
    UIImage *bg = [UIImage imageNamed:...];
    [test setBackgroundImage:bg forState:UIControlStateNormal];
    [test addTarget:self action:@selector(testAction) forControlEvents:UIControlEventTouchUpInside];
    [window addSubview:test];
    [test release];
    [window makeKeyAndVisible];
}

- (void)testAction {
    NSLog(@"Write something...");
}

完美运行!

但如果我用相同的代码创建一个空的 UIViewController:

- (void)viewDidLoad {
    UIButton *test = [[UIButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 100.0)];
    [test setTitle:@"Title" forState:UIControlStateNormal];
    UIImage *bg = [UIImage imageNamed:...];
    [test setBackgroundImage:bg forState:UIControlStateNormal];
    [test addTarget:self action:@selector(testAction) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:test];
    [test release];
    [window makeKeyAndVisible];
}

- (void)testAction {
    NSLog(@"Write something...");
}

我收到了这个神秘的错误。 :-( 救命!

【问题讨论】:

    标签: iphone uibutton uicontrol uncaught-exception


    【解决方案1】:

    myButton 在哪里被声明? 如果是合成的,那么代替

    rightButton = [UIButton buttonWithType:UIButtonTypeCustom];

    使用

    self.rightButton = [UIButton buttonWithType:UIButtonTypeCustom];
    

    应该可以。如果没有,请发布您如何声明该属性。

    【讨论】:

    • 我不认为这是这里的问题。这个视图控制器以编程方式创建它的视图(根本没有 xib 文件)。按钮只是类中的一个实例变量(不是属性),因此: self.rightButton = ... 根本无法编译。我什至在代码中创建了一个按钮。 UIButton *button2 = [UIButton buttonWithType:UIButtonTypeCustom]; ... [self.view addSubview:button2];当我不添加目标和操作时,按钮会呈现并正常运行。当我添加功能 (addTarget:action:forEvents:) 时,单击会引发异常。
    【解决方案2】:

    解决方案!

    我的问题是我在 AppDelegate 中使用了以下代码:

    UIViewController *controller = [[MyCustomController alloc] init];
    [window addSubview:controller.view];
    [controller release];
    

    所以只有视图控制器的视图属性被保留,其他所有东西都被清除了。视图控制器没有任何功能(没有触摸事件,没有实例方法)。这就是 addTarget:action:forEvents: 不起作用的原因。

    所以,聪明点 - 在 AppDelegate 的 dealloc 中释放您的视图控制器。 ;)

    【讨论】:

    • 引入 ARC 后,解决方案略有不同。现在你需要在头文件中声明 UIViewController *controller。所以它是类的成员变量,它在内部保留。只是不要像你知道的那样使用 ARC 来调用 release。
    【解决方案3】:

    一个旧帖子,现在可能已全部排序,但还有另一个问题会导致崩溃:

    [test addTarget:self action:@selector(testAction) forControlEvents:UIControlEventTouchUpInside]
    

    不正确。 action:@selector(testAction) 必须有一个冒号,因此:

    action:@selector(testAction:)
    

    否则你会得到一个无法识别的选择器崩溃——这就是你得到的......

    【讨论】:

    • 我希望我能为此投票给你+100,你只是为我节省了几个小时的抓挠时间。如果你错过了冒号设置一个没有 ID 的选择器目标 - 但用处不大。添加冒号执行魔术。我很少见过如此晦涩难懂且容易遗漏的代码
    • 是的 --- 我自己也遇到了这个问题 --- 冒号很关键 --- 谢天谢地 skajam66 写下这个回复。
    • 这个问题会在你输入冒号后忘记的时候发生。它说“我有一个参数”,然后如果你忘记了那个参数,它会说“发生了什么!有人给我们设置了信号!” “崩溃屏幕打开”“无法识别的选择器属于”......基本上这个问题是普遍的。不过很好发现
    猜你喜欢
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 2013-10-19
    • 2017-06-06
    • 2011-04-23
    • 1970-01-01
    • 2016-11-30
    相关资源
    最近更新 更多