iOS開發學習之NSTimer失效、NSTimer與runloop之間的關係、解密NSTimer
阿新 • • 發佈:2019-01-23
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
會預設為我們新增到Runloop
的NSDefaultRunLoopMode
中,而且由於是在主執行緒中,所以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
中,最後一定不要忘記呼叫Runloop
的run
方法將當前Runloop
開啟,否則NSTimer
永遠也不會執行。