iOS開發,定時器的使用
在iOS開發中,我們可以通過三種途徑來實現定時調用某一個方法的功能。為了簡便期間,我直接在Xcode中寫代碼以及注釋。
首先我們定義一個被定時執行的方法
- (void)reloop { NSLog(@"迴圈執行");}
下邊我們分別討論這三種方法
1、使用NSTimer
// 1、使用nstimer建立定時器 // A.自動加入主迴圈 NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(reloop) userInfo:nil repeats:YES]; // 啟用定時器 [timer fire];// 在迴圈調用時,必須手動釋放定時器,否則不必手動釋放 [timer invalidate];
// B.手動加入主迴圈 NSTimer *timer = [NSTimer timerWithTimeInterval:2 target:self selector:@selector(reloop) userInfo:nil repeats:YES]; [timer fire]; [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
注意,由於線程可能會阻塞,所以這種方法建立出來的定時器肯呢過會被延遲
2、使用CADisplayLink
// 螢幕重新整理時調用 // CADisplayLink是一個能讓我們以和螢幕重新整理率同步的頻率將特定的內容畫到螢幕上的定時器類。CADisplayLink以特定模式註冊到runloop後,每當螢幕顯示內容重新整理結束的時候,runloop就會向CADisplayLink指定的target發送一次指定的selector訊息, CADisplayLink類對應的selector就會被調用一次。所以通常情況下,按照iOS裝置螢幕的重新整理率60次/秒 // 延遲 // iOS裝置的螢幕重新整理頻率是固定的,CADisplayLink在正常情況下會在每次重新整理結束都被調用,精確度相當高。但如果調用的方法比較耗時,超過了螢幕重新整理周期,就會導致跳過若干次回調調用機會。 // 如果CPU過於繁忙,無法保證螢幕60次/秒的重新整理率,就會導致跳過若干次調用回調方法的機會,跳過次數取決CPU的忙碌程度。 // 使用情境 // 從原理上可以看出,CADisplayLink適合做介面的不停重繪,比如視頻播放的時候需要不停地擷取下一幀用於介面渲染。 // 2.1建立出displaylink對象 CADisplayLink *displyLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(reloop)]; // 2.2 將該對象加入迴圈中 [displyLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; // 2.3再不需要時釋放(停止迴圈) [displyLink invalidate]; displyLink = nil;
3、使用GCD
// 只執行一次 double delayInSeconds = 2.0; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ // 執行事件 [self reloop]; }); // 重複執行 NSTimeInterval period = 1.0; //設定時間間隔 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_walltime(NULL, 0), period * NSEC_PER_SEC, 0); //每秒執行 dispatch_source_set_event_handler(_timer, ^{ //在這裡執行事件 [self reloop]; }); dispatch_resume(_timer);