利用类扩展解决NSTimer会保留目标对象

利用类扩展解决NSTimer会保留目标对象在程序开发中经常会遇到计时器, 比如促销活动的倒计时,发送短信验证码过段时间才允许第二次发送、设置一段倒计时。 这个api从ios 2.0就开始提供了,可以兼容较低版本的ios系统。可是由于Timer会保留target参数,所以这个api会比较容易造成循环引用。想象一下有一个自…

场景

在程序开发中经常会遇到计时器, 比如促销活动的倒计时,发送短信验证码过段时间才允许第二次发送、设置一段倒计时。

问题

这时会用到 下面这个api, scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: API_AVAILABLE(ios(2.0)), 这个api从ios 2.0就开始提供了,可以兼容较低版本的ios系统。可是由于Timer会保留target参数,所以这个api会比较容易造成循环引用。想象一下有一个自定义ViewController1,里边有个倒计时功能,很容易通过下边的代码实现:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    _timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(invokeTimer) userInfo:nil repeats:YES];
}

- (void)invokeTimer {
    NSLog(@"%@", self);
}
- (void)dealloc
{
    [_timer invalidate];
    NSLog(@"%s", __FUNCTION__);
}

每过一秒钟触发一次,触发方法会输出log,在dealloc中将timer置为无效。看似天衣无缝,但实际上,从自定义ViewController1返回时,并不会调用dealloc,原因就是上文中提到的NSTimer对target的保留。这样就会造成ViewController1的内存泄漏了。

解决思路

利用像下边这样的类扩展,此时Timer的target 不再是自定义ViewController1

typedef void (^TimerHandler) (NSTimer *);

@interface NSTimer (HandleRetainTarget)

@end

@implementation NSTimer(HandleRetainTarget)

+ (NSTimer *)Eoc_timerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (^)(NSTimer *timer))handler  {
    return [NSTimer scheduledTimerWithTimeInterval:interval target:[self class] selector:@selector(repeatTimer:) userInfo:[handler copy] repeats:YES];
}

+ (void)repeatTimer:(NSTimer *)timer {
    TimerHandler handler = timer.userInfo;
    if (handler) {
        handler(timer);
    }
}

@end

调用示例

__weak typeof (self) weakself = self;
_timer = [NSTimer Eoc_timerWithTimeInterval:1.0 repeats:YES block:^(NSTimer *timer) {
     [weakself invokeTimer];
}];

Demo Git 地址

截图

点击Button -> 点击Back -> 查看log

利用类扩展解决NSTimer会保留目标对象
利用类扩展解决NSTimer会保留目标对象
!

利用类扩展解决NSTimer会保留目标对象

今天的文章利用类扩展解决NSTimer会保留目标对象分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/18068.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注