iOS中幾種定時器

在軟件開發(fā)過程中握础,我們常常需要在某個時間后執(zhí)行某個方法辐董,或者是按照某個周期一直執(zhí)行某個方法。在這個時候禀综,我們就需要用到定時器简烘。

然而苔严,在iOS中有很多方法完成以上的任務(wù),到底有多少種方法呢孤澎?經(jīng)過查閱資料届氢,大概有三種方法:NSTimer、CADisplayLink覆旭、GCD退子。接下來我就一一介紹它們的用法。

一型将、NSTimer

1. 創(chuàng)建方法
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(action:) userInfo:nil repeats:NO];
  • TimerInterval : 執(zhí)行之前等待的時間寂祥。比如設(shè)置成1.0,就代表1秒后執(zhí)行方法

  • target : 需要執(zhí)行方法的對象茶敏。

  • selector : 需要執(zhí)行的方法

  • repeats : 是否需要循環(huán)

2. 釋放方法

[timer invalidate];

注意 :
調(diào)用創(chuàng)建方法后壤靶,target對象的計數(shù)器會加1,直到執(zhí)行完畢惊搏,自動減1贮乳。如果是循環(huán)執(zhí)行的話,就必須手動關(guān)閉恬惯,否則可以不執(zhí)行釋放方法向拆。

3. 特性

存在延遲
不管是一次性的還是周期性的timer的實際觸發(fā)事件的時間,都會與所加入的RunLoop和RunLoop Mode有關(guān)酪耳,如果此RunLoop正在執(zhí)行一個連續(xù)性的運算浓恳,timer就會被延時出發(fā)。重復(fù)性的timer遇到這種情況碗暗,如果延遲超過了一個周期颈将,則會在延時結(jié)束后立刻執(zhí)行,并按照之前指定的周期繼續(xù)執(zhí)行言疗。

必須加入Runloop
使用上面的創(chuàng)建方式晴圾,會自動把timer加入MainRunloop的NSDefaultRunLoopMode中。如果使用以下方式創(chuàng)建定時器噪奄,就必須手動加入Runloop:

NSTimer *timer = [NSTimer timerWithTimeInterval:5 target:self selector:@selector(timerAction) userInfo:nil repeats:YES];

[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
4. NSTimer會是準(zhǔn)時觸發(fā)事件嗎

答案是否定的死姚,而且有時候你會發(fā)現(xiàn)實際的觸發(fā)時間跟你想象的差距還比較大。NSTimer不是一個實時系統(tǒng)勤篮,因此不管是一次性的還是周期性的timer的實際觸發(fā)事件的時間可能都會跟我們預(yù)想的會有出入都毒。差距的大小跟當(dāng)前我們程序的執(zhí)行情況有關(guān)系,比如可能程序是多線程的碰缔,而你的timer只是添加在某一個線程的runloop的某一種指定的runloopmode中账劲,由于多線程通常都是分時執(zhí)行的,而且每次執(zhí)行的mode也可能隨著實際情況發(fā)生變化。
  假設(shè)你添加了一個timer指定2秒后觸發(fā)某一個事件涤垫,但是簽好那個時候當(dāng)前線程在執(zhí)行一個連續(xù)運算(例如大數(shù)據(jù)塊的處理等)姑尺,這個時候timer就會延遲到該連續(xù)運算執(zhí)行完以后才會執(zhí)行竟终。重復(fù)性的timer遇到這種情況蝠猬,如果延遲超過了一個周期,則會和后面的觸發(fā)進(jìn)行合并统捶,即在一個周期內(nèi)只會觸發(fā)一次榆芦。但是不管該timer的觸發(fā)時間延遲的有多離譜,他后面的timer的觸發(fā)時間總是倍數(shù)于第一次添加timer的間隙喘鸟。

二匆绣、CADisplayLink

1. 創(chuàng)建方法
self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleDisplayLink:)];    

[self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
2. 停止方法
[self.displayLink invalidate];  

self.displayLink = nil;

當(dāng)把CADisplayLink對象add到runloop中后,selector就能被周期性調(diào)用什黑,類似于重復(fù)的NSTimer被啟動了崎淳;執(zhí)行invalidate操作時,CADisplayLink對象就會從runloop中移除愕把,selector調(diào)用也隨即停止拣凹,類似于NSTimer的invalidate方法。

3. 特性
  • 屏幕刷新時調(diào)用
    CADisplayLink是一個能讓我們以和屏幕刷新率同步的頻率將特定的內(nèi)容畫到屏幕上的定時器類恨豁。CADisplayLink以特定模式注冊到runloop后嚣镜,每當(dāng)屏幕顯示內(nèi)容刷新結(jié)束的時候,runloop就會向CADisplayLink指定的target發(fā)送一次指定的selector消息橘蜜, CADisplayLink類對應(yīng)的selector就會被調(diào)用一次菊匿。所以通常情況下,按照iOS設(shè)備屏幕的刷新率60次/秒

  • 延遲
    iOS設(shè)備的屏幕刷新頻率是固定的计福,CADisplayLink在正常情況下會在每次刷新結(jié)束都被調(diào)用跌捆,精確度相當(dāng)高。但如果調(diào)用的方法比較耗時象颖,超過了屏幕刷新周期佩厚,就會導(dǎo)致跳過若干次回調(diào)調(diào)用機會。
    如果CPU過于繁忙力麸,無法保證屏幕60次/秒的刷新率可款,就會導(dǎo)致跳過若干次調(diào)用回調(diào)方法的機會,跳過次數(shù)取決CPU的忙碌程度克蚂。

  • 使用場景
    從原理上可以看出闺鲸,CADisplayLink適合做界面的不停重繪,比如視頻播放的時候需要不停地獲取下一幀用于界面渲染埃叭。

4. 重要屬性
  • frameInterval
    NSInteger類型的值摸恍,用來設(shè)置間隔多少幀調(diào)用一次selector方法,默認(rèn)值是1,即每幀都調(diào)用一次立镶。

  • duration
    readOnly的CFTimeInterval值壁袄,表示兩次屏幕刷新之間的時間間隔。需要注意的是媚媒,該屬性在target的selector被首次調(diào)用以后才會被賦值嗜逻。selector的調(diào)用間隔時間計算方式是:調(diào)用間隔時間 = duration × frameInterval。

三: GCD的定時器 (最為準(zhǔn)確)

首先缭召,我們知道NStimer是在RunLoop的基礎(chǔ)上執(zhí)行的栈顷,然而RunLoop是在GCD基礎(chǔ)上實現(xiàn)的,所以說GCD可算是更加高級嵌巷。

- (void)gcdTimerConfig{
    self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());

    dispatch_source_set_timer(self.timer, DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);

    dispatch_source_set_event_handler(self.timer, ^{
        NSLog(@"xsxsxsxs");
    });

    dispatch_resume(self.timer);
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末萄凤,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子搪哪,更是在濱河造成了極大的恐慌靡努,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,525評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件晓折,死亡現(xiàn)場離奇詭異惑朦,居然都是意外死亡,警方通過查閱死者的電腦和手機已维,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評論 3 395
  • 文/潘曉璐 我一進(jìn)店門行嗤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人垛耳,你說我怎么就攤上這事栅屏。” “怎么了堂鲜?”我有些...
    開封第一講書人閱讀 164,862評論 0 354
  • 文/不壞的土叔 我叫張陵栈雳,是天一觀的道長。 經(jīng)常有香客問我缔莲,道長哥纫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,728評論 1 294
  • 正文 為了忘掉前任痴奏,我火速辦了婚禮蛀骇,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘读拆。我一直安慰自己擅憔,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,743評論 6 392
  • 文/花漫 我一把揭開白布檐晕。 她就那樣靜靜地躺著暑诸,像睡著了一般蚌讼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上个榕,一...
    開封第一講書人閱讀 51,590評論 1 305
  • 那天篡石,我揣著相機與錄音,去河邊找鬼西采。 笑死凰萨,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的苛让。 我是一名探鬼主播沟蔑,決...
    沈念sama閱讀 40,330評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼湿诊,長吁一口氣:“原來是場噩夢啊……” “哼狱杰!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起厅须,我...
    開封第一講書人閱讀 39,244評論 0 276
  • 序言:老撾萬榮一對情侶失蹤仿畸,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后朗和,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體错沽,經(jīng)...
    沈念sama閱讀 45,693評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,885評論 3 336
  • 正文 我和宋清朗相戀三年眶拉,在試婚紗的時候發(fā)現(xiàn)自己被綠了千埃。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,001評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡忆植,死狀恐怖放可,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情朝刊,我是刑警寧澤耀里,帶...
    沈念sama閱讀 35,723評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站拾氓,受9級特大地震影響冯挎,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜咙鞍,卻給世界環(huán)境...
    茶點故事閱讀 41,343評論 3 330
  • 文/蒙蒙 一房官、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧续滋,春花似錦翰守、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春事示,著一層夾襖步出監(jiān)牢的瞬間早像,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評論 1 270
  • 我被黑心中介騙來泰國打工肖爵, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留卢鹦,地道東北人。 一個月前我還...
    沈念sama閱讀 48,191評論 3 370
  • 正文 我出身青樓劝堪,卻偏偏與公主長得像冀自,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子秒啦,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,955評論 2 355

推薦閱讀更多精彩內(nèi)容