在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);