You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让@selector跨@implementation生效?Objective-C按钮点击无响应

问题解决:UIButton跨类绑定Selector不执行的原因与无ViewController依赖方案

问题根源

你代码里的核心问题是临时对象被ARC自动释放:在addTarget:中直接传入[[MyObject alloc] init]生成的对象,没有任何强引用持有它,当前函数执行完毕后ARC会立刻回收这个对象。当用户点击按钮时,目标对象已经不存在,自然无法触发showTerminal方法。

无ViewController依赖的解决方案

以下两种方案均不需要依赖ViewController,且能保证目标对象始终存活:

方案1:使用单例模式(推荐)

将MyObject实现为单例,确保整个APP生命周期内对象唯一且不会被释放:

@implementation MyObject

// 线程安全的单例实现
+ (instancetype)sharedInstance {
    static MyObject *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
}

- (void)showTerminal {
    NSLog(@"Terminal opened!");
}

@end

修改alert()函数中的addTarget行:

[sampleButton addTarget:[MyObject sharedInstance] action:@selector(showTerminal) forControlEvents:UIControlEventTouchDown];

方案2:使用全局变量持有对象

在alert()函数所在文件的顶部声明全局变量:

MyObject *globalMyObject;

然后在alert()函数内初始化并赋值:

globalMyObject = [[MyObject alloc] init];
[sampleButton addTarget:globalMyObject action:@selector(showTerminal) forControlEvents:UIControlEventTouchDown];

额外注意

  • 确保showTerminal方法的签名符合UIControl的要求:允许无参数,或带一个UIButton*类型的参数(你当前的写法是合规的)。
  • 给UIAlertController添加自定义视图时,建议使用AutoLayout约束替代固定Frame,避免不同机型上的布局错乱(这不是方法不执行的原因,但属于优化点)。

内容的提问来源于stack exchange,提问作者Jack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 14:22:08