乐趣区

关于ios: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 就被开释了;且不便在其余中央操作,如暂停、勾销、置空。
退出移动版