60s倒计时最佳实现 iOS

实现倒计时有三种方式:NStimer、CADisplayLink、dispatch_source_t

NStimer受runloop周期影响,精确度最低。

CADisplayLink 精确度高,但是受屏幕刷新频率影响,目前FPS是60hz。如果苹果官方改了,兼容性差

下面是dispatch_source_t的实现方式,并进行了封装,便于调用

+ (void)initWithGCD:(int)timeValue beginState:(void (^)(NSInteger time))begin endState:(void (^)(void))end {
    __block NSInteger time = timeValue;
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC, 0);
    dispatch_source_set_event_handler(timer, ^{
        if (time <= 0) {
            dispatch_source_cancel(timer);
            dispatch_async(dispatch_get_main_queue(), ^{
                if (end) {
                    end();
                }
            });
        } else {
            dispatch_async(dispatch_get_main_queue(), ^{
                if (begin) {
                    begin(time);
                }
            });
            time--;
        }
    });
    dispatch_resume(timer);
}

调用方式:

    [HZSTimer initWithGCD:60 beginState:^(NSInteger seconds){
        [self.codeBtn setTitle:[NSString stringWithFormat:@"%ld秒",(long)seconds] forState:UIControlStateNormal];
        self.codeBtn.userInteractionEnabled = NO;
        NSLog(@"%ld",(long)seconds);
    } endState:^() {
        [self.codeBtn setTitle:@"重新发送" forState:UIControlStateNormal];
        self.codeBtn.userInteractionEnabled = YES;
    }];
在北京的灯中,有一盏是我家的。这个梦何时可以实现?哪怕微微亮。北京就像魔鬼训练营,有能力的留,没能力的走……
原文地址:https://www.cnblogs.com/huangzs/p/14464126.html