美文网首页
定时器NSTimer,CADisplayLink,dispatc

定时器NSTimer,CADisplayLink,dispatc

作者: 七秒归零 | 来源:发表于2021-12-26 15:01 被阅读0次

    1、NSTimer特性

           timer实际触发事件的时间与runloop有关,如果此时的runloop在执行一个耗时运算,timer就会被延时触发。重复性的timer遇到这种情况,如果延迟超过一个周期,则会在延时结束后立即执行,并按照之前指定的周期继续执行。

            必须加入runloop,使用scheduledTimerWithTimeInterval创建的,会自动加入mainrunloop中NSDefaultRunloopMode中,如果使用其他方式创建,需要手动加入runloop

    NSTimer*timer=[NSTimer timerWithTimeInterval:6 target:selfselector:@selector(timerAction)userInfo:nil repeats:YES];

    [[NSRunLoop mainRunLoop]addTimer:timer forMode:NSDefaultRunLoopMode];

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

    2.CADisplayLink特性

            CADisplayLink是一个以屏幕刷新率将特定的内容画到屏幕上的定时器。CADisplayLink以特定模式注册到runloop后,每当屏幕刷新显示内容结束,runloop就会向CADisplayLink指定的targret发送一次指定的selector消息,CADisplayLink类对应的selector就会调用一次。

            延迟iOS设备的屏幕刷新频率是固定的,CADisplayLink在正常的情况下,会再每次刷新结束调用,精度高,但是在调试的方法比较耗时时,超过了屏幕的刷新周期,就会导致跳过若干次回调机会,如果CPU过于繁忙,无法保证屏幕的60次/秒的刷新率,就会导致跳过若干次回调的机会,跳过次数取决于CPU的忙碌程度。

    使用场景:

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


    3.dispatch_source_t

    与NSTimer和CADisplayLink相比,时间更准确,可以使用子线程,解决时间在主线程卡UI问题。

    NSTimer会受到主线程的任务影响,CADisplayLink会受到CPU的负载影响,产生延误。

    dispatch_source_t可以使用子线程,而且使用leeway参数指定可以接受的误差来降低资源的消耗。

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

    dispatch_source_t的suspendhe和resume要依次进行,不然毁crash,而且必须现在resume的转台下才能执行cancel,不然也会crash.

    @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,就可以重复利用该定时器了!!当我页面销毁的时候,要主动将定时器销毁掉:



    相关文章

      网友评论

          本文标题:定时器NSTimer,CADisplayLink,dispatc

          本文链接:https://www.haomeiwen.com/subject/srkyqrtx.html