技术

dispatch_source_t定时器

2019-05-13  本文已影响0人  那样风采

定时器简述

在iOS中,计时器是比较常用的,用于统计累加数据或者倒计时等,计时器大概有那么三种,分别是:

    NSTimer
    CADisplayLink
    dispatch_source_t

比较

1、NSTimer特性:

NSTimer *timer = [NSTimer timerWithTimeInterval:5 target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
image.png

如果选择的mode是default的话,当滑动scrollView的时候,定时器是会停止的,你可以将mode设置为common。

2、CADisplayLink特性

特性:

使用场景:
从原理上可以看出,CADisplayLink适合做界面的不停重绘,比如视频播放的时候需要不停地获取下一帧用于界面渲染。

3、dispatch_source_t特性

优点:

对比

dispatch_source_t使用实例

dispatch_source_t是可以重复利用的,当我们在一个页面上,需要多次用到时钟的话,可以将dispatch_source_t保存为属性,避免提前释放,然后循环挂起和恢复,就可以达到多次利用的效果:

@property (nonatomic, strong) dispatch_source_t timer;
@property (nonatomic, assign) BOOL isSuspend; //定时器挂起状态

isSuspend记录下挂起的状态,因为dispatch_source_t的suspend和resume要依次进行,不然会crash,而且必须在resume的状态下,才能执行cancel,不然也会crash!!isSuspend默认为YES,因为首次需要resume以启动定时器!

- (dispatch_source_t)timer
{
    if (!_timer) {
        _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
        uint64_t interval = (uint64_t)(XYHeyMediaPhotoTimerInterval * NSEC_PER_SEC);
        dispatch_source_set_timer(_timer, DISPATCH_TIME_NOW, interval, 0);
        @weakify(self);
        dispatch_source_set_event_handler(_timer, ^{
            dispatch_async(dispatch_get_main_queue(), ^{
                @strongify(self);
                [self updatePhotoProgress];
            });
        });
    }
    return _timer;
}

创建定时器,设置线程,启动时间,时间间隔,以及执行block,如果只执行一次,在block中调用cancel即可,我们这里默认为repeat!

- (void)resumeTimer
{
    if (self.isSuspend) {
        dispatch_resume(self.timer);
        self.isSuspend = NO;
    }
}

在需要启动时钟的时候调用上述方法resumeTimer,只有在已挂起的状态才能执行成功,同理,挂起操作:

- (void)suspendTimer
{
    if (!self.isSuspend) {
        dispatch_suspend(self.timer);
        self.isSuspend = YES;
    }
}

利用resumeTimer和suspendTimer,就可以重复利用该定时器了!!
当我页面销毁的时候,要主动将定时器销毁掉:

- (void)dealloc
{
    if (_timer) {
        if (_isSuspend) {
            dispatch_resume(_timer);
        }
        dispatch_source_cancel(_timer);
        _timer = nil;
    }
}

后续再补充一个封装好的定时器!!定时器

上一篇下一篇

猜你喜欢

热点阅读