美文网首页
NSTimer循环引用

NSTimer循环引用

作者: 磊Se | 来源:发表于2021-04-13 11:17 被阅读0次

    循环引用原因:

    初始化NSTimer的时候,传入的target会被NSTimer强引用,并且控制器强引用NSTimer,所以产生循环引用。

        self.timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
        [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
    

    解决方案

    1)合适的时机调用invalidate方法
    - (void)viewDidDisappear {
        [super viewDidDisappear];
        [self.timer invalidate];
    }
    
    2)target使用中间类,解决循环引用

    我们可以添加一个中间类,将TimerProxytarget设为弱引用并指向当前控制器就不会产生循环引用了

    代码:

    - (void)viewDidLoad {
        [super viewDidLoad];
        
        self.timer = [NSTimer timerWithTimeInterval:1.0 target:[TimerProxy timerProxyWithTarget:self] selector:@selector(timerAction) userInfo:nil repeats:YES];
        [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
    
    }
    
    @interface TimerProxy : NSObject
    @property (nonatomic, weak) id target;
    + (instancetype)timerProxyWithTarget:(id)target;
    @end
    
    @implementation TimerProxy
    + (instancetype)timerProxyWithTarget:(id)target
    {
        TimerProxy *instance = [TimerProxy new];
        instance.target = target;
        
        return instance;
    }
    
    - (id)forwardingTargetForSelector:(SEL)aSelector
    {
        return self.target;
    }
    @end
    

    这里使用到了runtime消息转发机制,forwardingTargetForSelector将消息转发给当前视图控制器,解决循环引用。

    相关文章

      网友评论

          本文标题:NSTimer循环引用

          本文链接:https://www.haomeiwen.com/subject/movqlltx.html