您的位置:首页 > 移动开发 > IOS开发

【iOS沉思录】如何创建NSTimer并使其在当前线程中正常运行?

2018-02-01 10:30 549 查看
NSTimer主要用于开启定时任务,但要真确使用才能保证其正常有效运行。尤其要注意以下两点:

确保NSTimer已经添加到当前RunLoop;

确保当前RunLoop已经启动。

1.创建NSTimer有两种方法:

+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;


这两种方法的主要区别为,使用timerWithTimeInterval创建的timer不会自动添加到当前RunLoop中,需要手动添加并制定RunLoop的模式:[[NSRunLoop currentRunLoop] addTimer:mainThreadTimer forMode:NSDefaultRunLoopMode]; 而使用scheduledTimerWithTimeInterval创建的RunLoop会默认自动添加到当前RunLoop中。

2.NSTimer可能在主线程中创建,也可能在子线程中创建:

主线程中的RunLoop默认是启动的,所以timer只要添加到主线程RunLoop中就会被执行;而子线程中的RunLoop默认是不启动的,所以timer添加到子线程RunLoop中后,还要手动启动RunLoop才能使timer被执行。

NSTimer只有添加到启动起来的RunLoop中才会正常运行。NSTimer通常不建议添加到主线程中执行,因为界面的更新在主线程中,界面导致的卡顿会影响NSTimer的准确性。

以下为四种情形下正确的使用方法:

- (void)viewDidLoad {
[super viewDidLoad];
/* 主线程中创建timer */
NSTimer *mainThreadTimer = [NSTimer timerWithTimeInterval:10.0 target:self selector:@selector(mainThreadTimer_SEL) userInfo:nil repeats:YES];
NSTimer *mainThreadSchduledTimer = [NSTimer scheduledTimerWithTimeInterval:10.0 target:self selector:@selector(mainThreadSchduledTimer_SEL) userInfo:nil repeats:YES];
/* 将mainThreadTimer1添加到主线程runloop */
[[NSRunLoop currentRunLoop] addTimer:mainThreadTimer forMode:NSDefaultRunLoopMode];

/* 子线程中创建timer */
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSTimer *subThreadTimer = [NSTimer timerWithTimeInterval:10.0 target:self selector:@selector(subThreadTimer_SEL) userInfo:nil repeats:YES];
NSTimer *subThreadSchduledTimer = [NSTimer scheduledTimerWithTimeInterval:10.0 target:self selector:@selector(subThreadSchduledTimer_SEL) userInfo:nil repeats:YES];
/* 将subThreadTimer1添加到子线程runloop */
[[NSRunLoop currentRunLoop] addTimer:subThreadTimer forMode:NSDefaultRunLoopMode];
/* 启动子线程runloop */
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
});
}

- (void) mainThreadTimer_SEL{
NSLog(@"mainThreadTimer is working!");
}
- (void) mainThreadSchduledTimer_SEL{
NSLog(@"mainThreadSchduledTimer is working!");
}

- (void) subThreadTimer_SEL{
NSLog(@"subThreadTimer is working!");
}
- (void) subThreadSchduledTimer_SEL{
NSLog(@"subThreadSchduledTimer is working!");
}


打印结果为:

2018-01-31 20:24:10.729259+0800 IOSDemo[41891:4382661] mainThreadSchduledTimer is working!
2018-01-31 20:24:20.728351+0800 IOSDemo[41891:4382661] mainThreadTimer is working!
2018-01-31 20:24:20.728409+0800 IOSDemo[41891:4382720] subThreadTimer is working!
2018-01-31 20:24:20.728693+0800 IOSDemo[41891:4382720] subThreadSchduledTimer is working!


NSTimer的释放方法:

[timer invalidate];
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐