標簽(空格分隔): 計時器 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)有代碼提示啦背稼!](http://ww2.sinaimg.cn/large/64e5447ajw1f4c1wmcw2hj21kw0ddn4v.jpg)
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)驗證碼倒計時
![計時器](http://ww4.sinaimg.cn/large/64e5447ajw1f4cp0ub9b7j20sg0sgq6m.jpg)
計時器
// 開啟倒計時效果
- (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);
}