標籤:
1.背景介紹:NSTimer是什麼鬼
這貨大家從它的『臉』估計就能知道它是啥東西了,是的,計時器。但是,如果你說NSTimer就是計時器,肯定會有人說你太業餘,叫法不準確,然後以一個大牛的姿態說一些正常人聽不懂的並且帶有諷刺味道的話。呵呵,這都不重要,因為大家都是被大牛虐出來的,今後也會去虐別人。重要的是NSTimer能幹什麼,這才是我們關心的,至於它的定義或者概念是什麼,還是交給英語系的童鞋去操心吧。所以,在介紹NSTimer的功能之前,我們還姑且就把它叫做計時器吧,它能做的就是從現在開始到後面的某一個時刻或者周期性的執行我們指定的方法的對象。
2.使用NSTimer之前要瞭解的知識
(1)NSTimer有以下兩個常用的方法
+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo;
建立一個計時器,參數1:時間間隔(秒),參數2:表示發送的對象(一般填self),參數3:要執行的方法,參數4:傳遞資訊(可以以字典的形式,將資訊傳遞給要執行的方法),參數5:是否重複執行,如果NO,timer執行一次後便失效。
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo;
建立一個計時器,參數1:時間間隔(秒),參數2:表示發送的對象(一般填self),參數3:要執行的方法,參數4:傳遞資訊(可以以字典的形式,將資訊傳遞給要執行的方法),參數5:是否重複執行,如果NO,timer執行一次後便失效。
大家可能發現了,第一個方法和第二個方法貌似是一樣的?是的,他們基本是一樣的,但是也是有一些區別的,繼續向下看,你會知道它們的不同之處的。
(2)運行迴圈RunLoop
不知道大家有沒有想過這個問題,一個應用開始運行以後放在那裡,如果不對它進行任何操作,這個應用就像靜止了一樣,不會自發的有任何動作發生,但是如果我們點擊介面上的一個按鈕,這個時候就會有對應的按鈕響應事件發生。給我們的感覺就像應用一直處於隨時待命的狀態,在沒人操作的時候它一直在休息,在讓它幹活的時候,它就能立刻響應。其實,這就是run loop的功勞。(此段話寨子CSDN)
大家可以把運行迴圈理解成一個系統級的線程,它時刻在監聽著系統各種事件,一旦有事件發生,他就會觸發處於運行迴圈中的程式。NSTimer也一樣,只有加入運行迴圈中才能正常運行。但是,加入運行迴圈也是分好多種情況的,就像我們去上班,高富帥開車去,普通青年做地鐵去,文藝青年不去。NSTimer加入運行迴圈常見的有兩種模式,第一種是預設模式(NSDefaultRunLoopModel),第二種是(NSRunLoopCommonModels)。
(3)timerWithTimeInterval和scheduledTimerWithTimeInterval的區別
知道了運行迴圈的兩種模式,我們就能說清楚這兩個方法有什麼區別了。scheduledTimerWithTimeInterval方法建立完timer之後,會自動以NSDefaultRunLoopModel模式加入運行迴圈。而timerWithTimeInterval方法建立的timer,不會自動加入運行迴圈,需要我們手動指定模式,並手動加入運行迴圈。
至於這兩種模式又有什麼不同,接下來我們會通過代碼得到答案。
3.一些例子
例1:
以上例子說明:scheduledTimerWithTimeInterval方法建立timer後,即可加入運行迴圈進行執行,userinfo資訊可通過參數攜帶到方法中。
例2:
同樣是上述代碼,我們在介面中加入了textView控制項,在計時器執行的過程中,我們拖動textView控制項,發現計時器會中斷,停止拖動textView後,計時器繼續執行。
以上代碼說明,在預設模式下(NSDefaultRunLoopModel),當有滾動事件發生,運行迴圈就會暫時停止NSTimer的執行,當滾動事件結束後,再繼續執行NSTimer計時器。那麼,在另外一種模式(NSRunLoopCommonModels)下又會是怎樣的呢。我們一起再來看看,當然,想要使用NSRunLoopCommonModels模式,我們就要用timerWithTimeInterval方法來建立timer了。
例3:
在上述代碼中我們發現,在NSRunLoopCommonModels模式下,無論我們怎麼滾動視圖,NSTimer也會正常執行的。
以上例子說明了這兩種模式表現出來的現象,其實這兩種模式的區別是:
NSDefaultRunLoopModel:監聽使用者最基本的操作(點擊,觸摸等)
NSRunLoopCommonModels:監聽一些特殊操作:滾動等
那麼,為什麼在NSDefaultRunLoopModel模式下發生滾動,計時器會停止呢?那是因為系統認為,使用者不應該邊滾動邊操作介面,所以停止了(觸碰,點擊等)NSDefaultRunLoopModel模式下監聽的事件。
4.使用NSTimer是不準確的計時
假設NSTimer要執行 A,B,C,D四個任務,當執行到B的時候被中斷,那麼,當NStimer獲得繼續執行的權利之後,會把B,C一起執行。換句話說,NSTimer不會遺漏任務,但也無法保證按時準確執行任務。那麼,ios中怎麼保證準時執行任務呢?一般情況下,我們會使用CADisplayLink。它會在螢幕每次重新整理時執行一次。而螢幕的重新整理頻率每秒要達到幾十次,從而保證的時間的準確性。
以上內容是個人對NSTimer膚淺的認識,今後如果有進一步的瞭解,還會對文章進行更新。歡迎大家批評指正。
(完)
ios開發中NSTimer的基本使用