iOS開發,常常需要我們在某個時間刷新視圖,或者請求數據。這時,我們需要使用定時器。iOS中的定時方法很多,這里有三種比較常見的方法,沒有絕對的優劣性,只是不同的應用場景,使用不同的方法。
一、NSTimer
1.特點
我們可以指定一個時間,讓timer一次性的或者周期性的觸發一個自定義的方法。但是timer有個需要注意的地方。timer可能會存在延時,不管是一次性的還是周期性的timer,都會與RunLoop和RunLoop Mode有關,如果這個RunLoop正在執行一個連續性的運算,timer就會延時出發。重復性的timer遇到這種情況,如果延遲超過了一個周期,則會在延時結束后立刻執行,并按照之前指定的周期繼續執行。
2.NSTimer的創建方法
(1)自動加入RunLoop的創建方法
/**
* 方法一
**/
NSTimer *times1=[NSTimer scheduledTimerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
//可以直接在代碼塊中編寫你要執行的代碼
}];
/**
* 方法二:@selector()中寫你要執行的方法
**/
NSTimer *time2=[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(run:) userInfo:nil repeats:YES];
注意:如果repeats為Yes,我們還需要在執行完畢的時候,手動的銷毀,否者會造成內存泄漏,如下:
//手動釋放timer的方法
[timer invalidate];
(2)需要手動加入RunLoop的創建方法
NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(run:) userInfo:nil repeats:YES];
//手寫代碼,加入runLoop
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
二、CADisplayLink
1.特點
該方法會在屏幕刷新時被調用,CADisplayLink是一個能讓調用頻率與屏幕的刷新率同步的定時器類。CADisplayLink是以特定模式注冊到runloop后,每當屏幕顯示內容刷新結束的時候(通常iOS設備屏幕的刷新率60次/秒),runloop就會向CADisplayLink指定的target發送一次指定的selector消息, 也就是說,CADisplayLink類對應的selector就會被調用一次。
但是,這個刷新方法同樣有可能遇到延時的情況,比如:iOS設備的屏幕刷新頻率是固定的,CADisplayLink在正常情況下會在每次刷新結束都被調用,精確度相當高。但如果調用的方法比較耗時,超過了屏幕的刷新周期,就會導致跳過若干次回調調用的機會。還有一種情況是CPU過于繁忙,無法保證屏幕60次/秒的刷新頻率,就會導致跳過若干次調用回調方法的機會,跳過次數完全取決于CPU的忙碌程度。
從原理上可以看出,CADisplayLink適合做界面的重繪。
2.CADisplayLink的創建方法
CADisplayLink *displayLink=[CADisplayLink displayLinkWithTarget:self selector:@selector(run:)];
//frameInterval屬性是用來設置方法的調用間隔的,有時候我們并不需要這么快的調用頻率。
//我們就可以自己定義多少幀調用一次,frameInterval的默認值是1,如果是5,相當于每秒調用12次(60/5)。
displayLink.frameInterval=5;
//執行了下面一行代碼,相當于定時器啟動了,selector就能被周期性調用,如果想要停止,往下看!
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
定時器停止的方法
[displayLink invalidate];
displayLink = nil;
如何計算方法調用的時間間隔吶?
CADisplayLink中有個duration屬性,該屬性在target的selector被首次調用以后才會被賦值。selector的調用間隔時間計算方式是:調用間隔時間 = duration × frameInterval。
注意,duration只能讀,不能寫!
三、GCD
1.特點
GCD很強大,這里只寫其中的兩個用法,如果要想詳細的了解GCD。
傳送門:(叮咚!) GCD詳解 <-點這里
2.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){
//執行事件
});
第二種:重復執行
創建的方法:
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); //如果period==1,就是每秒執行
dispatch_source_set_event_handler(_timer, ^{
//在這里執行事件
});
暫停定時器的方法如下,在需要的地方調用即可:
dispatch_resume(_timer);
【有什么沒寫清楚的,下方留言!】