NSTimer 總結1(包括計時器不準的解決)

記得自己剛接觸nstimer時,以為就是個定時循環執行某方法的計時器,然而之后遇到過各種問題,最近發現問的最多的就是頁面滑動時計時器不準的情況,下邊我總結一下自己長久以來收集到的信息.

1.基礎使用方法

非新手請自動濾過

 /* NSTimer計時器類    
 TimeInterval:設定執行時間    
 target:目標    
 @selector:方法(也就是目標(target)的行為(selector))  
 userInfo:用于向selector方法中傳參數,  一般是self
 repeats:是否重復
     */
NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval:.9 target:self selector:@selector(changeColor:) userInfo:view4 repeats:YES];    
[timer fire];//開始執行

//計時器執行的方法,sender 就是對應的計時器(那個計時器調的我)
- (void)changeColor:(NSTimer *)sender
{    
//sender計時器對象,通過.userinfo屬性就能拿到當初傳來的參數(id類型),
對于此題上面穿的是一個view對象,所以直接用UIview類型接收   
 UIView * vie = sender.userInfo;   
 //修改傳入視圖的背景色   
 vie.backgroundColor = [UIColor colorWithRed:arc4random() % 256 / 255.0 green:arc4random() % 256 / 255.0 blue:arc4random() % 256 / 255.0 alpha:1.0];
}

2.開始和暫停

NSTimer 是木有暫停繼續的方法的,只有fire和invalidate,前者是開工的意思,后者是廢掉的意思,如果用廢掉來代替暫停的功能?顯然是不對的。

那腫么辦呢?
其實NSTimer 有一個屬性叫 fireDate ,啥意思呢?fireDate么,就是fire 的開始時間所以我們就有了思路了。

暫停: [timer setFireDate:[NSDate distantFuture]]; distantFuture,就是問你未來有多遠呢?好遠好遠就是無法到達的時間,所以 timer就一直等待不 fire了。也就是暫停了。

繼續: [timer setFireDate:[NSDate date]]; 這個當然就是把fire 的時間設置為當前時刻,所以timer就立刻開工啦!

3.解決滑動頁面計時器不準情況

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

在做界面滑動等操作時,計時器會不準

導致誤差的原因是我在使用“scheduledTimerWithTimeInterval”方法時,NSTimer實例是被加到當前runloop中的,模式是NSDefaultRunLoopMode。而“當前runloop”就是應用程序的main runloop,此main runloop負責了所有的主線程事件,這其中包括了UI界面的各種事件。當主線程中進行復雜的運算,或者進行UI界面操作時,由于在main runloop中NSTimer是同步交付的被“阻塞”,而模式也有可能會改變。因此,就會導致NSTimer計時出現延誤。

解決這種誤差的方法,一種是在子線程中進行NSTimer的操作,再在主線程中修改UI界面顯示操作結果;另一種是仍然在主線程中進行NSTimer操作,但是將NSTimer實例加到main runloop的特定mode(模式)中。避免被復雜運算操作或者UI界面刷新所干擾。
這里我經常用的是他:

[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];

[NSRunLoop currentRunLoop]獲取的就是“main runloop”,使用NSRunLoopCommonModes模式,將NSTimer加入其中。其他方法后續再補充.
比如我在自己寫的倒計時中就用到了這句:http://www.lxweimin.com/p/6ce30bd28fe7
關于runloop就比較高端了,我捉摸透了希望也可以總結下
未完待續

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Run loop 剖析:Runloop 接收的輸入事件來自兩種不同的源:輸入源(intput source)和定時...
    Mitchell閱讀 12,490評論 17 111
  • 前言 最近離職了,可以盡情熬夜寫點總結,不用擔心第二天上班爽并蛋疼著,這篇的主角 RunLoop 一座大山,涵蓋的...
    zerocc2014閱讀 12,436評論 13 67
  • 之前要做一個發送短信驗證碼的倒計時功能,打算用NSTimer來實現,做的過程中發現坑還是有不少的。 基本使用 NS...
    WeiHing閱讀 4,408評論 1 8
  • 轉載:http://www.cocoachina.com/ios/20150601/11970.html RunL...
    Gatling閱讀 1,471評論 0 13
  • 很久沒有開口說整串整串的英語句子,一直以為自己的功底還在,但是這兩天的練習真的大大的打擊了我。在模仿的過程中,最大...
    波西米婭閱讀 146評論 0 0