iOS - GCD 實現(xiàn)定時器账嚎、倒計時

標簽(空格分隔): 計時器 GCD timer 倒計時


GCD 定時器

NSTimer 的定時器是在 RunLoop 中實現(xiàn)的郭蕉,由于RunLoop在處理各種任務喂江,所以會造成計時器不夠準確,有時候會相對慢一些涨岁,有沒有什么方法會讓計時變得準確筐付?有,使用 GCD 的計時器方法會讓計時器變得相對準確沮尿,而且GCD不受RunLoop的 Mode 影響较解。

GCD 延時

我們之前寫過延時執(zhí)行的方法印衔,其中 GCD 有一個延時執(zhí)行的方法,瞎暑,只執(zhí)行一次与帆,執(zhí)行完后,就不再執(zhí)行.如下代碼在這里等待兩秒鐘后執(zhí)行勿她,執(zhí)行之后就結束了阵翎,不能起到定時器的作用.

//延時執(zhí)行
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    
    NSLog(@"-------延時執(zhí)行--------");
});

GCD 定時器的實現(xiàn)

GCD 計時器,蘋果已經(jīng)有代碼提示啦背稼!
GCD 計時器辩恼,蘋果已經(jīng)有代碼提示啦!

在之前寫一個GCD的定時器很麻煩疆前,需要一步步創(chuàng)建聘萨,現(xiàn)在XCode中已經(jīng)有Timer的創(chuàng)建提示,選擇箭頭所指的方法胸完,直接能過創(chuàng)建翘贮。

如下:

  dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, <#dispatchQueue#>);
dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, <#intervalInSeconds#> * NSEC_PER_SEC, <#leewayInSeconds#> * NSEC_PER_SEC);
dispatch_source_set_event_handler(timer, ^{
    <#code to be executed when timer fires#>
});
dispatch_resume(timer);

我們需要做的是狸页,選擇其隊列類型,這里我選擇的是全局隊列址遇。

創(chuàng)建 計時器 (參數(shù)注解)

/**
 *   GCD 計時器應用
 *   dispatch Queue :決定了將來回調的方法在哪里執(zhí)行斋竞。
 *   dispatch_source_t timer  是一個OC對象
 *   DISPATCH_TIME_NOW  第二個參數(shù):定時器開始時間,也可以使用如下的方法,在Now 的時間基礎上再延時多長時間執(zhí)行以下任務浸剩。

 dispatch_time(<#dispatch_time_t when#>, <#int64_t delta#>)
 
 *   intervalInSeconds  第三個參數(shù):定時器開始后的間隔時間(納秒 NSEC_PER_SEC)
 *  leewayInSeconds 第四個參數(shù):間隔精準度乒省,0代標最精準畦木,傳入一個大于0的數(shù)砸泛,代表多少秒的范圍是可以接收的,主要為了提高程序性能,積攢一定的時間勾栗,Runloop執(zhí)行完任務會睡覺围俘,這個方法讓他多睡一會,積攢時間簿寂,任務也就相應多了一點宿亡,而后一起執(zhí)行
 */

 // 全局隊列
dispatch_queue_t  queue = dispatch_get_global_queue(0, 0);

// 創(chuàng)建一個 timer 類型定時器 ( DISPATCH_SOURCE_TYPE_TIMER)
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);

//設置定時器的各種屬性(何時開始挽荠,間隔多久執(zhí)行)
// GCD 的時間參數(shù)一般為納秒 (1 秒 = 10 的 9 次方 納秒)
// 指定定時器開始的時間和間隔的時間
dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC, 0);

// 任務回調
dispatch_source_set_event_handler(timer, ^{
    NSLog(@"-----定時器-------");
});

// 開始定時器任務(定時器默認開始是暫停的,需要復位開啟)
dispatch_resume(timer);

GCD實現(xiàn)驗證碼倒計時

計時器
計時器
// 開啟倒計時效果

- (IBAction)openCountdown:(id)sender {
    

    __block NSInteger time = 59; //倒計時時間
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    
    dispatch_source_set_timer(timer,DISPATCH_TIME_NOW,1.0*NSEC_PER_SEC, 0); //每秒執(zhí)行
    
    dispatch_source_set_event_handler(timer, ^{
        
        if(time <= 0){ //倒計時結束,關閉
            
            dispatch_source_cancel(timer);
            
            dispatch_async(dispatch_get_main_queue(), ^{
                
                //設置按鈕的樣式
                [self.openSeconds setTitle:@"重新發(fā)送" forState:UIControlStateNormal];
                self.timeLabel.text = @"開始";

                self.openSeconds.userInteractionEnabled = YES;
            });
            
        }else{

            int seconds = time % 60;
            dispatch_async(dispatch_get_main_queue(), ^{
                
                
                //設置label讀秒效果
                self.timeLabel.text = [NSString stringWithFormat:@"重新發(fā)送(%.2d)",seconds];
                
                [self.openSeconds setTitle:@"已發(fā)送" forState:UIControlStateNormal];
                // 在這個狀態(tài)下 用戶交互關閉笆搓,防止再次點擊 button 再次計時
                self.openSeconds.userInteractionEnabled = NO;

            });
                 
            time--;
        }
    });
                 
    dispatch_resume(timer);
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末砚作,一起剝皮案震驚了整個濱河市嘹锁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌米同,老刑警劉巖摔竿,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件继低,死亡現(xiàn)場離奇詭異,居然都是意外死亡柴底,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門狐树,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人抑钟,你說我怎么就攤上這事野哭。” “怎么了虐拓?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵心俗,是天一觀的道長。 經(jīng)常有香客問我蓉驹,道長城榛,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任态兴,我火速辦了婚禮狠持,結果婚禮上,老公的妹妹穿的比我還像新娘瞻润。我一直安慰自己喘垂,他們只是感情好,可當我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布绍撞。 她就那樣靜靜地躺著正勒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪傻铣。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天非洲,我揣著相機與錄音鸭限,去河邊找鬼。 笑死两踏,一個胖子當著我的面吹牛败京,可吹牛的內容都是我干的。 我是一名探鬼主播梦染,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼赡麦,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起隧甚,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤车荔,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后戚扳,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡族吻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年帽借,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片超歌。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡砍艾,死狀恐怖,靈堂內的尸體忽然破棺而出巍举,到底是詐尸還是另有隱情脆荷,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布懊悯,位于F島的核電站蜓谋,受9級特大地震影響,放射性物質發(fā)生泄漏炭分。R本人自食惡果不足惜桃焕,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望捧毛。 院中可真熱鬧观堂,春花似錦、人聲如沸呀忧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽而账。三九已至胰坟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間福扬,已是汗流浹背腕铸。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留铛碑,地道東北人狠裹。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像汽烦,于是被迫代替她去往敵國和親涛菠。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內容