iOS开发----UI部分-----NSTimer定时器的使用及相关问题

1. NSTimer 不是很精确

2.CADisplayLink 屏幕

3.通过GCD来实现定时间器

//定时循环执行事件

//dispatch_source_set_timer 方法值得一提的是最后一个参数(leeway),他告诉系统我们需要计时器触发的精准程度。

所有的计时器都不会保证100%精准,这个参数用来告诉系统你希望系统保证精准的努力程度。

如果你希望一个计时器每5秒触发一次,并且越准越好,那么你传递0为参数。

另外,如果是一个周期性任务,比如检查email,那么你会希望每10分钟检查一次,但是不用那么精准。

所以你可以传入60,告诉系统60秒的误差是可接受的。他的意义在于降低资源消耗。

 // 在全局队列里面

_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, globalQueue);

 // 设置每隔多久时间执行

dispatch_source_set_timer(_timer, DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC, 0.0 * NSEC_PER_SEC);

 // 执行事件

dispatch_source_set_event_handler(_timer, ^{ //计时器事件处理器

    DLog(@"Event Handler");

    if (timeout <= 0) {

        dispatch_source_cancel(_timer); //取消定时循环计时器;使得句柄被调用,即事件被执行

        dispatch_async(mainQueue, ^{

            if (![CMAdManager shareInstance].launchAdClicked) {

                if (!self.skipButton.selected) {

                    [self skipAction:self.skipButton];

                }

            }

        });

    } else {

        NSString *strTime = [NSString stringWithFormat:@"%d S跳过", timeout];

        // 在主队列里面执行

        dispatch_async(mainQueue, ^{

            [self.skipButton setTitle:strTime forState:UIControlStateNormal];

        });

        timeout--;

    }

});

// 句柄

dispatch_source_set_cancel_handler(_timer, ^{

   //计时器取消处理器;调用 dispatch_source_cancel 时执行

    DLog(@"Cancel Handler");

});

// 

dispatch_resume(_timer);

//恢复定时循环计时器;Dispatch Source 创建完后默认状态是挂起的,需要主动恢复,否则事件不会被传递,也不会被执行

 

 

 

对比

CADisplayLink 与 NSTimer 有什么不同

iOS设备的屏幕刷新频率是固定的,CADisplayLink在正常情况下会在每次刷新结束都被调用,精确度相当高。
NSTimer的精确度就显得低了点,比如NSTimer的触发时间到的时候,runloop如果在阻塞状态,触发时间就会推迟到下一个runloop周期。并且 NSTimer新增了tolerance属性,让用户可以设置可以容忍的触发的时间的延迟范围。
CADisplayLink使用场合相对专一,适合做UI的不停重绘,比如自定义动画引擎或者视频播放的渲染。NSTimer的使用范围要广泛的多,各种需要单次或者循环定时处理的任务都可以使用。在UI相关的动画或者显示内容使用 CADisplayLink比起用NSTimer的好处就是我们不需要在格外关心屏幕的刷新频率了,因为它本身就是跟屏幕刷新同步的。

 

posted on 2016-12-01 19:03  1018475062  阅读(432)  评论(0编辑  收藏  举报