iOS的幾種定時器

在開發中我們經常用到定時器,iOS爲我們提供了多種定時器,包括NSTimer、CADisplayLink、GCD。

NSTimer

iOS中最基本的定時器,其通過RunLoop來實現,一般情況下較爲準確,但當前循環耗時操作較多時,會出現延遲問題。同時,也受所加入的RunLoop的RunLoopMode影響,如果因爲創建的NSTimer 默認是被加入到了 defaultMode,比如在一個視圖裏面滑動tableview,當 RunloopMode 變化時,當前的 NSTimer 就不會工作,故我們使用NSTimer需要用NSRunLoopCommonModes。

創建

NSTimer *timer1 = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(timerMethod1) userInfo:nil repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

釋放

定時器的釋放一定要先將其終止,而後才能銷燬對象。

invalidate 、timer置爲nil 防止循環引用。

GCD

GCD定時器是dispatch_source_t類型的變量,其可以實現更加精準的定時效果。

    dispatch_queue_t queue1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue1);
    self.timer = timer;
    dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
    dispatch_source_set_event_handler(timer, ^{
        NSLog(@"%@",[NSThread currentThread]);
    });
    dispatch_resume(timer);

CADisplayLink

CADisplayLink是基於屏幕刷新的週期,所以其一般很準時,每秒刷新60次。其本質也是通過RunLoop,所以不難看出,當RunLoop選擇其他模式或被耗時操作過多時,仍舊會造成延遲。

CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(test)];
[link addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

使用CADisplayLink自己的addToRunLoop:forMode:方法,同時,由於其是基於屏幕刷新的,所以也度量單位是每幀,其提供了根據屏幕刷新來設置間隔的frameInterval屬性,其決定於屏幕刷新多少幀時調用一次該方法,默認爲1,即1/60秒調用一次。

總結

iOS設備的屏幕刷新頻率是固定的,CADisplayLink在正常情況下會在每次刷新結束都被調用,精確度相當高。

NSTimer的精確度就顯得低了點,比如NSTimer的觸發時間到的時候,runloop如果在阻塞狀態,觸發時間就會推遲到下一個runloop週期。並且 NSTimer新增了tolerance屬性,讓用戶可以設置可以容忍的觸發的時間的延遲範圍。

CADisplayLink使用場合相對專一,適合做UI的不停重繪,比如自定義動畫引擎或者視頻播放的渲染。NSTimer的使用範圍要廣泛的多,各種需要單次或者循環定時處理的任務都可以使用。在UI相關的動畫或者顯示內容使用 CADisplayLink比起用NSTimer的好處就是我們不需要在格外關心屏幕的刷新頻率了,因爲它本身就是跟屏幕刷新同步的。

NSTimer和CADisplayLink都需要加入runloop。

GCD更準時的原因,我們可以發現GCD定時器實際上是使用了dispatch源(dispatch source),dispatch源監聽系統內核對象並處理。dispatch類似生產者消費者模式,通過監聽系統內核對象,在生產者生產數據後自動通知相應的dispatch隊列執行,後者充當消費者。通過系統級調用,更加精準。

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