如何让@selector跨@implementation生效?Objective-C按钮点击无响应
问题根源
你代码里的核心问题是临时对象被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
相关产品推荐
相关产品推荐

