ios NSTimer和GCDtimer对比

NSTimer这个大家用的比较多,

    _timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
    // 取消的时候
    [self.timer invalidate];
    self.timer = nil;

gcd的timer代码量有点大,


    dispatch_queue_t queue = dispatch_queue_create("hhh", DISPATCH_QUEUE_SERIAL);
    // timer要做成属性或者成员变量
    self.gcdTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    dispatch_source_set_timer(self.gcdTimer, DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC, 0.5 * NSEC_PER_SEC);
    dispatch_source_set_event_handler(self.gcdTimer, ^{

        NSLog(@"gcd的timer fire");
        
    });
    dispatch_resume(self.gcdTimer);
    
    // 演示如何取消定时器
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        // 取消定时器
        dispatch_cancel(self.gcdTimer);
    });

 

用法很简单,主要比对下2者的区别 : 

  • NSTimer 需要一个运行的Runloop 来处理其定时任务, MainThread是一直启动并运行的,默认加入了NSDefaultRunLoopMode
  • 在自定的线程如果使用NSTIme必须手动开启并运行子线程的Runloop,[[NSRunLoop currentRunLoop] run]; 并且销毁子线程的timer也必须在子线程中,也就是说创建和 invalidate必须放在相同的线程中进行
  • NSTimer 必须调用 invalidate 来停止其定时任务,并且NSTimer 对其Target是强引用,要注意Target 与 - NSTimer间造成的循环引用造成的内存泄漏(可以封装一个类别来解决此问题)
  • NSTimer 的fire函数,相当于立即调用一个绑定的事件,对原来的时间周期没有影响
  • GCDTimer 是基于GCD实现的,使用的时候只要我们把任务提交给相应队列就好
  • GCDTimer 在使用时要注意 dispatch_resume(obj) dispatch_suspend(obj) -dispatch_source_cancel(obj)API 的使用
  • GCDTimer 在对文件资源定期进行读写操作时很方便,其他与NSTimer使用场景差不多

 

NSTimer不准时的原因:
1:RunLoop循环处理的时间,可能某个时刻runloop需要处理很多任务,会导致NSTimer的精度降低,
2:受RunLoop模式的影响,如果NSTimer没有加入到NSRunLoopCommonModes的话,就会受到UITrackingRunLoopMode和NSDefaultRunLoopMode的切换影响

gcd的timer与NSTimer是不同的
1:都是源,而NSTimer是RunLoop的源 ;gcd的timer是dispatch的源,,dispatch_source_t精度很高,系统自动触发。

2:gcd的timer不需要加入mode,那么就不会受到切换模式的影响了



 

你可能感兴趣的:(ios NSTimer和GCDtimer对比)