GCD 定时器

Swift

var timer : DispatchSourceTimer?

func startTimer() {    
    var timeCount = 10
    // 在global线程里创建一个时间源
    if timer == nil {
        timer = DispatchSource.makeTimerSource(queue: DispatchQueue.global())
    }
    // 设定这个时间源是每秒循环一次,立即开始
    timer?.schedule(deadline: .now(), repeating: .seconds(1))
    // 设定时间源的触发事件
    timer?.setEventHandler(handler: {
        //此时处于 global 线程中
        print("定时器:",timeCount)
        // 每秒计时一次
        timeCount = timeCount - 1
        // 时间到了取消时间源
        if timeCount <= 0 {
            self.stopTimer() 
            DispatchQueue.main.async {
                //UI操作放在主线程
                
            }     
        }
    })
    // 启动时间源
    timer?.resume()
}

//停止定时器
func stopTimer() {
    print("定时器结束")
    timer?.cancel()
    timer = nil
}

Objective-C

@interface ViewController ()
{
    dispatch_source_t _timer;
}
@end

-(void)startTimer{
    __block NSInteger timeCount = 10;
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(0, 0));
    dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
    dispatch_source_set_event_handler(timer, ^{
        NSLog(@"定时器:%li",(long)timeCount);
        timeCount --;
        if (timeCount <= 0) {
            [self stopTimer];
            dispatch_async(dispatch_get_main_queue(), ^{
                
            });
        }
        
    });
    dispatch_resume(timer);
    _timer = timer;
    
}

-(void)stopTimer{
    dispatch_source_cancel(_timer);
    _timer = nil;
}

有两点需要注意:

  • 照此方法停止定时器,可以复用,使用suspend停止定时器无法复用
  • timer 要设置为全局对象。否则代码执行完后 timer 就被释放了;且方便在其他地方操作,如暂停、取消、置空。

你可能感兴趣的:(GCD 定时器)