1. 程式人生 > >iOS 計時器三種定時器的用法NSTimer、CADisplayLink、GCD

iOS 計時器三種定時器的用法NSTimer、CADisplayLink、GCD

並且 reat clas 就會 固定 tro run mod 不同

原文:http://www.cocoachina.com/ios/20160919/17595.html

一、三種計時器

二、全局倒計時

#import "ViewController.h"

@interface ViewController ()

{
    
    CADisplayLink * displaylinked;
}
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
   
//1 timer 會有延遲不夠精確 [self tiemred]; //2。CADisplayLink 適合UI刷新動畫 [self cadisplayLink]; //3 GCD精確度高 [self GcdTimer]; } -(void)GcdTimer{ //GCD的定時器和NSTimer是不一樣的,NSTimer受RunLoop影響,但是GCD的定時器不受影響,因為RunLoop也是基於GCD的 //1 執行1次 double delayInseconds = 2.0;//間隔時間 dispatch_time_t poptimer
= dispatch_time(DISPATCH_TIME_NOW, delayInseconds * NSEC_PER_SEC); dispatch_after(poptimer, dispatch_get_main_queue(), ^{ //執行事件 }); //重復執行 NSTimeInterval period = 1.0 ;//時間間隔 dispatch_queue_t queuet = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0
); dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queuet); dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, period * NSEC_PER_SEC, 0 * NSEC_PER_SEC); dispatch_source_set_event_handler(timer, ^{ //執行事件 }); dispatch_resume(timer); } -(void)cadisplayLink{ //創建 displaylinked = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayAction:)]; //加入RunLoop [displaylinked addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; /* CADisplayLink是一個能讓我們以和屏幕刷新率同步的頻率將特定的內容畫到屏幕上的定時器類。 CADisplayLink以特定模式註冊到runloop後, 每當屏幕顯示內容刷新結束的時候,runloop就會向 CADisplayLink指定的target發送一次指定的selector消息, CADisplayLink類對應的selector就會被調用一次。 iOS設備的屏幕刷新頻率是固定的,CADisplayLink在正常情況下會在每次刷新結束都被調用,精確度相當高。使用場合相對專一,適合做UI的不停重繪,比如自定義動畫引擎或者視頻播放的渲染。不需要在格外關心屏幕的刷新頻率了,本身就是跟屏幕刷新同步的*/ /*CADisplayLink 與 NSTimer 有什麽不同 iOS設備的屏幕刷新頻率是固定的,CADisplayLink在正常情況下會在每次刷新結束都被調用,精確度相當高。 NSTimer的精確度就顯得低了點,比如NSTimer的觸發時間到的時候,runloop如果在阻塞狀態,觸發時間就會推遲到下一個runloop周期。並且 NSTimer新增了tolerance屬性,讓用戶可以設置可以容忍的觸發的時間的延遲範圍。 CADisplayLink使用場合相對專一,適合做UI的不停重繪,比如自定義動畫引擎或者視頻播放的渲染。NSTimer的使用範圍要廣泛的多,各種需要單次或者循環定時處理的任務都可以使用。在UI相關的動畫或者顯示內容使用 CADisplayLink比起用NSTimer的好處就是我們不需要在格外關心屏幕的刷新頻率了,因為它本身就是跟屏幕刷新同步的。 下面結合NSTimer來介紹 CADisplayLink,與NSTimer不同的地方有: 1、原理不同 CADisplayLink是一個能讓我們以和屏幕刷新率同步的頻率將特定的內容畫到屏幕上的定時器類。 CADisplayLink以特定模式註冊到runloop後, 每當屏幕顯示內容刷新結束的時候,runloop就會向 CADisplayLink指定的target發送一次指定的selector消息, CADisplayLink類對應的selector就會被調用一次。 NSTimer以指定的模式註冊到runloop後,每當設定的周期時間到達後,runloop會向指定的target發送一次指定的selector消息。 2、周期設置方式不同 iOS設備的屏幕刷新頻率(FPS)是60Hz,因此CADisplayLink的selector 默認調用周期是每秒60次,這個周期可以通過frameInterval屬性設置, CADisplayLink的selector每秒調用次數=60/ frameInterval。比如當 frameInterval設為2,每秒調用就變成30次。因此, CADisplayLink 周期的設置方式略顯不便。 NSTimer的selector調用周期可以在初始化時直接設定,相對就靈活的多。 3、精確度不同 iOS設備的屏幕刷新頻率是固定的,CADisplayLink在正常情況下會在每次刷新結束都被調用,精確度相當高。 NSTimer的精確度就顯得低了點,比如NSTimer的觸發時間到的時候,runloop如果在忙於別的調用,觸發時間就會推遲到下一個runloop周期。更有甚者,在OS X v10.9以後為了盡量避免在NSTimer觸發時間到了而去中斷當前處理的任務,NSTimer新增了tolerance屬性,讓用戶可以設置可以容忍的觸發的時間範圍。 4、使用場合 從原理上不難看出, CADisplayLink 使用場合相對專一, 適合做界面的不停重繪,比如視頻播放的時候需要不停地獲取下一幀用於界面渲染。 NSTimer的使用範圍要廣泛的多,各種需要單次或者循環定時處理的任務都可以使用。 */ } -(void)displayAction:(CADisplayLink*)display{ NSLog(@"沒一幀都在刷新"); //display 的取消 display.paused = YES; [display invalidate]; display = nil; } -(void)tiemred{ //timer計時器 //1 不循環 NSTimer * timerNo = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(timerAction:) userInfo:nil repeats:NO]; //循環的計時器 NSTimer * timerYes = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES]; //加入RunLoop 保證Runloop改變是timer正常工作 [[NSRunLoop currentRunLoop] addTimer:timerYes forMode:NSRunLoopCommonModes]; } -(void)timerAction:(NSTimer*)timer{ NSLog(@"計時器來了"); //計時器銷毀 // [timer invalidate]; // timer = nil; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end

iOS 計時器三種定時器的用法NSTimer、CADisplayLink、GCD