前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS NSTimer不走的问题

iOS NSTimer不走的问题

原创
作者头像
莫空9081
修改2020-08-19 10:08:01
1.3K0
修改2020-08-19 10:08:01
举报
文章被收录于专栏:iOS 备忘录

iOS NSTimer不走的问题

背景

这个版本上线后,突然发现埋点数据直线下降,调试后发现是定时器上传的方法没有走,但是定时器的方法本期并没有修改过。代码如下

代码语言:txt
复制
- (BOOL)initTimer() {
        self.uploadTimer = [NSTimer scheduledTimerWithTimeInterval:timerInterval target:self selector:@selector(handleUpload) userInfo:nil repeats:YES];
		[[NSRunLoop currentRunLoop] addTimer:self.uploadTimer forMode:NSRunLoopCommonModes];
}

排查

这个handleUpload方法,怎么都不会走,但是在之前的版本中就是好的,排查了之后发现,是外层调用的地方加了一层异步。即调用的地方变成了

代码语言:txt
复制
dispatch_async(dispatch_get_global_queue(0, 0), ^{
    initTimer()
});

然后就导致了定时器没有启动。

原因

iOS是通过runloop作为消息循环机制,主线程默认启动了runloop,可是自线程没有默认的runloop,因此,我们在子线程启动定时器是不生效的。

解决方法:在子线程启动一下runloop即可

代码语言:txt
复制
- (BOOL)initTimer() {
        self.uploadTimer = [NSTimer scheduledTimerWithTimeInterval:timerInterval target:self selector:@selector(handleUpload) userInfo:nil repeats:YES];
		[[NSRunLoop currentRunLoop] addTimer:self.uploadTimer forMode:NSRunLoopCommonModes];
        [[NSRunLoop currentRunLoop] run];
}

思考

通过这个问题,有两点收获,

  1. timer在iOS开发中经常使用,在很多博客中都看到关于timer要注意的地方也很多,通常是内存管理,timer启动相关,但是在开发中,如果没有真正遇到问题,没有“疼”在自己身上,就自己注意的就不够,经过这次之后,相信以后再要在异步使用timer,肯定会留心很多。
  2. 这个地方initTimer其实是一个SDK初始化的类,其实SDK内部没有修改,但是外层使用SDK的App调用修改了,就导致了SDK不能正常工作。所以封装SDK时要注意,如果使用timer,要么做线程检查,要么就直接把代码安全保证好;因为不能保证第三方调用者使用时的情况,所以要保证自己代码的正确性。

参考

IOS定时器操作和NSTimer的各种坑

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • iOS NSTimer不走的问题
    • 背景
      • 排查
        • 原因
          • 思考
            • 参考
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档