定時器的幾種實現方式

**一. 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{
    
    
    
}
```**

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