之前在項(xiàng)目中遇見了一個問題游岳,在子線程中如何開啟NSTimer和取消NSTimer”溃現(xiàn)在總結(jié)一下垛膝,當(dāng)做自己的筆記锤灿。
1.子線程中NSTimer的開啟
首先在.m文件中聲明兩個屬性一個是子線程 一個是子線程中的NSTimer。
@property (nonatomic, strong) NSThread *thread1;
@property (nonatomic, strong) NSTimer *threadTimer;
然后用GCD在全局全隊(duì)中創(chuàng)建一個子線程并創(chuàng)建NSTimer。
__weak __typeof(self) weakSelf = self;
dispatch_async(dispatch_get_global_queue(0, 0), ^{
__strong __typeof(weakSelf) strongSelf = weakSelf;
if (strongSelf) {
strongSelf.thread1 = [NSThread currentThread];
[strongSelf.thread1 setName:@"線程A"];
strongSelf.threadTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:strongSelf selector:@selector(timerAction) userInfo:nil repeats:YES];
NSRunLoop *runloop = [NSRunLoop currentRunLoop];
[runloop addTimer:strongSelf.threadTimer forMode:NSDefaultRunLoopMode];
[runloop run];
}
});
注意的是:在子線程中創(chuàng)建的NSTimer需要加入到對應(yīng)線程的RunLoop中克握。RunLoop中常用的mode有:NSDefaultRunLoopMode蕾管、UITrackingRunLoopMode和NSRunLoopCommonModes三種模式。
NSDefaultRunLoop 默認(rèn)模式
UITrackingRunLoop 界面追蹤菩暗,用于scrollView拖拽 滑動
NSRunLoopCommonModes 不是一個特定的模式掰曾,只是一種標(biāo)記,比較綜合的一種模式(包含 前兩種模式)
在NSTimer加入RunLoop后停团,需要將RunLoop運(yùn)行起來旷坦。
2.子線程中NSTimer的關(guān)閉
之后創(chuàng)建一個cancelTimer的方法
- (void)cancel{
if (self.threadTimer) {
[self.threadTimer invalidate];
self.threadTimer = nil;
}
}
如果這個方法跟創(chuàng)建NSTimer不在同一個線程執(zhí)行是無法將Timer 執(zhí)行invalidate操作的。
然后現(xiàn)在我們需要在thread1這個線程中執(zhí)行這個操作佑稠,在這里寫一個方法用于在子線程中調(diào)用此方法秒梅。
- (void)cancelTimer{
if (self.threadTimer && self.thread1) {
[self performSelector:@selector(cancel) onThread:self.thread1 withObject:nil waitUntilDone:YES];
}
}
最后我們在有需要關(guān)閉Timer的地方執(zhí)行此方法即可。
在這里說明一下為什么NSTimer要在同一個線程中創(chuàng)建和關(guān)閉舌胶。因?yàn)閯?chuàng)建的Timer的時候已經(jīng)把Timer加入到該線程對應(yīng)的RunLoop中捆蜀,這個RunLoop設(shè)置了這個Timer為一個事件。因此要在同一個線程中才能cancel這個Timer幔嫂。