iOS,子线程中NSTimer的开启和关闭

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_31177681/article/details/84993515

1.子线程中NSTimer的开启
首先在.m文件中声明两个属性一个是子线程 一个是子线程中的NSTimer。
@property (nonatomic, strong) NSThread *thread1;
 
@property (nonatomic, strong) NSTimer *threadTimer;
然后用GCD在全局全队中创建一个子线程并创建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];
        }
    });
注意的是:在子线程中创建的NSTimer需要加入到对应线程的RunLoop中。RunLoop中常用的mode有:NSDefaultRunLoopMode、UITrackingRunLoopMode和NSRunLoopCommonModes三种模式。

NSDefaultRunLoop 默认模式

UITrackingRunLoop 界面追踪,用于scrollView拖拽 滑动

NSRunLoopCommonModes 不是一个特定的模式,只是一种标记,比较综合的一种模式(包含 前两种模式)

在NSTimer加入RunLoop后,需要将RunLoop运行起来。

2.子线程中NSTimer的关闭
之后创建一个cancelTimer的方法

- (void)cancel{
 
if (self.threadTimer) {
 
[self.threadTimer invalidate];
 
self.threadTimer = nil;
 
}
 
}

如果这个方法跟创建NSTimer不在同一个线程执行是无法将Timer 执行invalidate操作的。

然后现在我们需要在thread1这个线程中执行这个操作,在这里写一个方法用于在子线程中调用此方法。
- (void)cancelTimer{
 
if (self.threadTimer && self.thread1) {
 
[self performSelector:@selector(cancel) onThread:self.thread1 withObject:nil waitUntilDone:YES];
 
}
 
}
最后我们在有需要关闭Timer的地方执行此方法即可。
在这里说明一下为什么NSTimer要在同一个线程中创建和关闭。因为创建的Timer的时候已经把Timer加入到该线程对应的RunLoop中,这个RunLoop设置了这个Timer为一个事件。因此要在同一个线程中才能cancel这个Timer。
 

猜你喜欢

转载自blog.csdn.net/sinat_31177681/article/details/84993515