iOS多線程的初步研究(四)-- NSTimer


理解run loop后,才能徹底理解NSTimer的實現原理,也就是說NSTimer實際上依賴run loop實現的。

先看看NSTimer的兩個常用方法:

+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo; //生成timer但不執行

+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo; //生成timer並且納入當前線程的run loop來執行

NSRunLoop與timer有關方法為:

- (void)addTimer:(NSTimer *)timer forMode:(NSString *)mode; //在run loop上注冊timer

主線程已經有run loop,所以NSTimer一般在主線程上運行都不必再調用addTimer:。但在非主線程上運行必須配置run loop,該線程的main方法示例代碼如下:

- (void)main

{

  NSTimer *myTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timer:) userInfo:nil repeats:YES];

  NSRunLoop *runLoop = [NSRunLoop currentRunLoop];

  [runLoop addTimer:myTimer forMode:NSDefaultRunLoopMode]; //實際上這步是不需要,scheduledTimerWithTimeInterval已經納入當前線程運行。如果使用timerWithTimeInterval則需要

  while (condition)

    [runLoop run];

}

實際上這個線程無法退出,因為有timer事件需要處理,[runLoop run]會一直無法返回。解決辦法就是設置一個截止時間:

[runLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:10.0]]; //每隔10秒檢查下線程循環條件,當然時間值可以根據實際情況來定。

 

我們通常在主線程中使用NSTimer,有個實際遇到的問題需要注意。當滑動界面時,系統為了更好地處理UI事件和滾動顯示,主線程runloop會暫時停止處理一些其它事件,這時主線程中運行的NSTimer就會被暫停。解決辦法就是改變NSTimer運行的mode(mode可以看成事件類型),不使用缺省的NSDefaultRunLoopMode,而是改用NSRunLoopCommonModes,這樣主線程就會繼續處理NSTimer事件了。具體代碼如下:

NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(timer:) userInfo:nil repeats:YES];

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

大家可以參看博文http://bluevt.org/?p=209,加深理解NSTimer和NSRunLoop的關系。

 

以前博文中提到延遲調用的方法,其實就是在當前線程的run loop上注冊timer來實現定時運行的。所以如果是在非主線程上使用,一定要有一個run loop。

- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay inModes:(NSArray *)modes;

- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM