定时器的几种实现方式

**一. ios端实现定时器的方式有以下三种方式
1).NSTimer
优点:使用方便,满足大多数需求,应用广泛
缺点:不太精准,受制于RunLoop,使用可能会造成内存泄露
使用:引导页,滑动页等等
2).GCD-Dispatch_source_t
优点:精度较高,系统自动触发,系统级别的源,不受制于RunLoop
缺点:时间事件可能被堵塞
使用:验证消息等待
3).CADisPlayLink
优点:刷新频率和设备屏幕同步,苹果手机屏幕60hz,每秒调用60次,依托设备触发事件,时间间隔最精准的定时器
缺点:CPU销毁过大,影响屏幕刷新,触发也会受影响,不能被继承
使用:和贝塞尔曲线+CAShapeLayer使用
二.具体实现
NSTimer

//创建方式1.默认添加到当前的runlooph中,默认defaultmodel 无需手动添加runloop中,会被其他事件打断
    _timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerUpData) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
   
    //创建方式2
    //需要手动添加到runloop中,不会回不执行定时器
    _timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(timerUpData) userInfo:nil repeats:YES];
    //方式一默认model,会被打断
    [[NSRunLoop currentRunLoop]addTimer:self.timer forMode:NSDefaultRunLoopMode];
    
    //方式二也会被打断
    [[NSRunLoop currentRunLoop]addTimer:self.timer forMode:UITrackingRunLoopMode];
    
    //方式三 组合model不会内打断
    [[NSRunLoop currentRunLoop]addTimer:self.timer forMode:NSRunLoopCommonModes];
    
    //销毁计时器
    [self.timer invalidate];
    
    
    //暂停计时器
    self.timer.fireDate = [NSDate distantFuture];
    //恢复计时器
    self.timer.fireDate = [NSDate distantPast];
    
    
    
    
    
    //子线程中使用
    __block NSTimer *disTimer;
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
       
        disTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerUpData) userInfo:nil repeats:YES];
       
        //启动线程
        [[NSRunLoop currentRunLoop] run];
    });

dispatch_soucrt

-(void)configDisPathSouorce{
    
    __block int timeOut = 30; //倒计时时间
    
    //创建异步队列,
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    //创建定时器
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    
    //开始时间
    dispatch_time_t startTime = dispatch_walltime(NULL,1.0*NSEC_PER_SEC);
    
   //间隔时间
    uint64_t interval = 1.0*NSEC_PER_SEC;
    //每秒执行
    dispatch_source_set_timer(timer,startTime, interval,0);
    
    
    
    dispatch_source_set_event_handler(timer, ^{
        
        //结束 关闭
        if (timeOut<=0) {
            
            dispatch_source_cancel(timer);
            dispatch_async(dispatch_get_main_queue(), ^{
                //主线程 按钮怎么显示或者挑转等等
            });
            
            
        }else{
            
            int seconds = timeOut%60;
            NSString *timeStr = [NSString stringWithFormat:@"%.2d",seconds];
            
            dispatch_async(dispatch_get_main_queue(), ^{
                //按钮显示 需求来
                NSLog(@"__%@",timeStr);
                
            });
            
            timeOut--;
        }
        
        
        
    });
    
    dispatch_resume(timer);
}

CADisPlayLink

-(void)configCADisplayLink{
    
    /*
     四个属性
     timestamp:获取上一次selector被执行的时间蔟,只读,需要selector执行一次之后才有值
     duration:获取当前设备屏幕刷新时间的间隔,只读属性,需要selector触发一次后有值
     
     
     
     
     */
    
    
    CADisplayLink *displayTime = [CADisplayLink displayLinkWithTarget:self selector:@selector(dispalychange)];
    
    //暂停 yes暂停 no不暂停
    displayTime.paused = YES;
    //触发间隔 弃用
    //displayTime.frameInterval = 2;
    //加入到runloop中
    [displayTime addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    
    //销毁
   // [displayTime invalidate];
    
}
-(void)dispalychange{
    
    
    
}
```**

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章