標籤:share 重新整理 cte with orm async 延遲 loop 方法
1. NSTimer 不是很精確
2.CADisplayLink 螢幕
3.通過GCD來實現定時間器
//定時迴圈執行事件
//dispatch_source_set_timer 方法值得一提的是最後一個參數(leeway),他告訴系統我們需要計時器觸發的精準程度。
所有的計時器都不會保證100%精準,這個參數用來告訴系統你希望系統保證精準的努力程度。
如果你希望一個計時器每5秒觸發一次,並且越准越好,那麼你傳遞0為參數。
另外,如果是一個週期性任務,比如檢查email,那麼你會希望每10分鐘檢查一次,但是不用那麼精準。
所以你可以傳入60,告訴系統60秒的誤差是可接受的。他的意義在於降低資源消耗。
// 在全域隊列裡面
_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, globalQueue);
// 設定每隔多久時間執行
dispatch_source_set_timer(_timer, DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC, 0.0 * NSEC_PER_SEC);
// 執行事件
dispatch_source_set_event_handler(_timer, ^{ //計時器事件處理器
DLog(@"Event Handler");
if (timeout <= 0) {
dispatch_source_cancel(_timer); //取消定時迴圈計時器;使得控制代碼被調用,即事件被執行
dispatch_async(mainQueue, ^{
if (![CMAdManager shareInstance].launchAdClicked) {
if (!self.skipButton.selected) {
[self skipAction:self.skipButton];
}
}
});
} else {
NSString *strTime = [NSString stringWithFormat:@"%d S跳過", timeout];
// 在主隊列裡面執行
dispatch_async(mainQueue, ^{
[self.skipButton setTitle:strTime forState:UIControlStateNormal];
});
timeout--;
}
});
// 控制代碼
dispatch_source_set_cancel_handler(_timer, ^{
//計時器取消處理器;調用 dispatch_source_cancel 時執行
DLog(@"Cancel Handler");
});
//
dispatch_resume(_timer);
//恢複定時迴圈計時器;Dispatch Source 建立完後預設狀態是掛起的,需要主動恢複,否則事件不會被傳遞,也不會被執行
對比
CADisplayLink 與
NSTimer 有什麼不同
iOS裝置的螢幕重新整理頻率是固定的,CADisplayLink在正常情況下會在每次重新整理結束都被調用,精確度相當高。
NSTimer的精確度就顯得低了點,比如NSTimer的觸發時間到的時候,runloop如果在阻塞狀態,觸發時間就會延遲到下一個runloop周期。並且 NSTimer新增了tolerance屬性,讓使用者可以設定可以容忍的觸發的時間的延遲範圍。
CADisplayLink使用場合相對專一,適合做UI的不停重繪,比如自訂動畫引擎或者視頻播放的渲染。NSTimer的使用範圍要廣泛的多,各種需要單次或者迴圈定時處理的任務都可以使用。在UI相關的動畫或者顯示內容使用 CADisplayLink比起用NSTimer的好處就是我們不需要在格外關心螢幕的重新整理頻率了,因為它本身就是跟螢幕重新整理同步的。
iOS中定時器的使用