iOS timer計時器

來源:互聯網
上載者:User

標籤:

timer,計時器,就是用來計時的,可以將它和要處理的動作綁定起來,讓這個動作在某段時間之後執行,或者周期性地執行。

一、timer的工作原理

timer的工作和run loop密不可分,由於平常我們使用Application Kit和UIKit來建立的app,在app的主線程啟動的時候就自動啟動了一個runloop,因此在主線程中使用timer感覺不到runloop的存在。如果要在分線程中使用timer,就必須要瞭解timer和runloop的協同工作原理,自己去建立runloop,讓它和timer一起配合工作。
簡短概括runloop和timer的工作關係就是,timer只負責計時,timer所綁定的動作,是由runloop來執行的。下面就來詳細地講講這種關係。
我們知道,runloop啟動並執行時候需要指定運行模式(run loop mode),runloop的運行模式規定了它要監聽的事件來源,以及事件發生時它要通知的對象。因此可以給runloop定義多種運行模式,runloop運行時,可以同時啟用多個運行模式。
一個timer同一時間只可以註冊到一個runloop中,但是可以添加到這個runloop的多個運行模式中。(表示了這個關係)

初始化一個timer,就是給timer綁定一個要執行的動作;登記一個時間段,這個時間段用來告訴runloop,該動作需要在該時間段過去之後執行,或者每隔這個時間段執行一次。
在timer與runloop的協同工作中,timer只負責計時,而runloop負責監視其所啟用的運行模式中添加的timer是否已經達到了其初始化時登記的時間,一旦發現某個timer已經到達了這個時間,就會去執行該timer所綁定的動作(這就是所謂的fire the timer)。
由此可以見得,timer所登記的這個時間段並不是動作的絕對執行時間。timer綁定的動作具體在什麼時候執行,要看runloop是否在運行,且是否啟用了timer所加入的運行模式,還要看runloop正在處理的東西多不多,能不能及時發現timer已經計時完畢。

二、timer的具體使用1、建立timer(1)使用當前的runloop來建立一個timer

方法:

+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo;
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;

參數TimeInterval是timer計時的周期長度,每隔時間長度TimeInterval,計時器就會清零一次。
這兩個方法,完成一系列動作:

  • 建立timer;
  • 將它加入到當前runloop的預設運行模式中;
  • 讓timer開始計時。

對於這種方式添加的timer,runloop就會等它的計時時間長度第一次達到TimeInterval時,才會執行它綁定的動作。

(2)自己建立一個timer,之後將它註冊到某個runloop中

方法:

+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo;
+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;

這兩個方法可以返回一個timer。

之後要用runloop對象的方法將timer註冊到這個runloop對象的某個運行模式中:

-(void)addTimer:(nonnull NSTimer *) forMode:(nonnull NSString *);

這樣添加到runloop的timer會立即開始計時。

(3)初始化一個timer,並指明它綁定的動作被執行的時間點

方法:

- (instanceType)initWithFireDate:(nonnull NSDate *) interval:(NSTimeInterval) target:(nonnull id) selector:(nonnull SEL) userInfo:(nullable id) repeats:(BOOL);

這裡的fireDate是個時間點,是相對於系統時間的,只要到達了這個時間點,runloop就會去執行timer綁定的動作。所以如果timer是一次性的,都不需要計時,interval這個參數就沒有作用了。如果是重複的timer,才需要計時,參數interval才有用。

可以用setFireDate方法來給timer設定動作的執行時間。

2、停止timer

timer需要在runloop的管理下才會有效,停止timer,只要把它從它所在的runloop中清理掉就可以實現。(或者讓runloop停止運行)。

(1)對於一次性的timer

一次性的timer都不用考慮這個問題,因為runloop執行完timer綁定的動作就會自動把這個timer從它所在的運行模式中清理掉。

(2)對於周期性的timer

方法:

-(void)invalidate;

對於周期性的timer才需要考慮這個問題。

要停止一個周期性的timer,要擷取這個timer對象的引用,在需要清理timer的時候,主動調用該timer對象的invalidate方法即可。

當然,也可以對一次性的timer執行這個方法,在timer的動作被runloop執行之前調用invalidate方法,timer的動作就永遠不會被執行了。

iOS timer計時器

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.