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

UISwitch添加跨类实例对象为target时回调失效问题求助

原因分析

你遇到的问题核心是ARC内存管理机制导致的:

  • 在无效代码中,[CustomClass alloc]创建的实例对象没有被任何强引用持有,ARC会在当前代码执行完毕后立即释放这个实例。当UISwitch触发UIControlEventValueChanged事件时,目标对象已经被销毁,自然无法调用实例方法test。
  • 类对象是全局唯一的单例对象,系统会一直持有它的强引用,不会被ARC释放,所以绑定类方法时,事件触发时目标对象始终存在,方法能正常执行。
解决方案

要让跨类实例方法正常被UISwitch调用,核心是保证target实例被强引用持有,常见的实现方式有两种:

方案1:将CustomClass实例声明为当前类的属性

在当前类的实现文件中添加强引用属性:

@property (strong, nonatomic) CustomClass *customInstance;

然后在创建UISwitch时,先初始化并持有这个实例:

@implementation CustomClass : NSObject
-(void) test {
    NSLog(@"TEST");
}
@end

// 在当前类的方法中
self.customInstance = [[CustomClass alloc] init];
UISwitch *uiSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(100, 100, 50, 50)];
[uiSwitch addTarget:self.customInstance action:@selector(test) forControlEvents:UIControlEventValueChanged];
[self addSubview:uiSwitch];

方案2:使用单例模式复用CustomClass实例

如果CustomClass的实例可以全局复用,将其设计为单例:

@implementation CustomClass : NSObject
+(instancetype)sharedInstance {
    static CustomClass *instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[CustomClass alloc] init];
    });
    return instance;
}

-(void) test {
    NSLog(@"TEST");
}
@end

绑定target时直接使用单例对象:

UISwitch *uiSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(100, 100, 50, 50)];
[uiSwitch addTarget:[CustomClass sharedInstance] action:@selector(test) forControlEvents:UIControlEventValueChanged];
[self addSubview:uiSwitch];

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 06:53:11