1. 程式人生 > >iOS開發學習之NSTimer失效、NSTimer與runloop之間的關係、解密NSTimer

iOS開發學習之NSTimer失效、NSTimer與runloop之間的關係、解密NSTimer

1. 今天在開發的時候,遇到NSTimer無效、所以也到網上找了一些資料,看看究竟怎麼回事兒、

    再次也做一次分享、方便有需要的朋友。

 1.   NSTimer是做什麼的?

1.簡單的理解就是一個定時器,在開發過程中,特定時間或者週期性去執行一個任務。

   一次性

[NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(createSoapClient) userInfo:nil repeats:NO];

   週期性

[NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(createSoapClient) userInfo:nil repeats:YES];

如果使用重複的NSTimer一定要有對應的invalidate,否則Timer會一直存在。
NSTimer會對target物件進行一次retain,所以我們要注意target物件的生命週期。

2.  NSTimer 為什麼失效? NStimer與runloop的關係?

runloop是什麼 ? 

 runloop是事件接收和分發機制的一個實現。

Run loops是執行緒的基礎架構部分。一個run loop就是一個事件處理迴圈,用來不停的調配工作以及處理輸入事件。使用run loop的目的是使你的執行緒在有工作的時候工作,沒有的時候休眠。

NSTimer *timer = [[NSTimer alloc]initWithFireDate:[NSDate dateWithTimeInterval:10 sinceDate:[NSDate date]] interval:1 target:self selector:@selector(createSoapClient) userInfo:nil repeats:YES];

   這兒的原因就是沒有吧這個NSTimer加入到runloop中去,所以沒有執行。 上面寫的程式碼為什麼就可以了,我們前面做演示的程式碼建立的NSTimer會預設為我們新增到RunloopNSDefaultRunLoopMode中,而且由於是在主執行緒中,所以Runloop是開啟的,不需要我們手動開啟,所以是可以執行的。 正確的程式碼如下
NSRunLoop *loop = [NSRunLoop currentRunLoop];
NSTimer *timer = [[NSTimer alloc]initWithFireDate:[NSDate dateWithTimeInterval:10 sinceDate:[NSDate date]] interval:1 target:self selector:@selector(createSoapClient) userInfo:nil repeats:YES];
[loop addTimer:timer forMode:NSDefaultRunLoopMode];
[loop run];

iOS多執行緒中,每一個執行緒都有一個Runloop,但是隻有主執行緒的Runloop預設是開啟的,其他子執行緒也就是我們建立的執行緒的Runloop預設是關閉的,需要我們手動執行。我們可以通過[NSRunLoop currentRunLoop]來獲得當前執行緒的Runloop,並且呼叫[runloop addTimer:timer forMode:NSDefaultRunLoopMode]方法將定時器新增到Runloop中,最後一定不要忘記呼叫Runlooprun方法將當前Runloop開啟,否則NSTimer永遠也不會執行。