一.NSRunloop的基本認(rèn)識(shí)
主線程Runlopp 從App開啟,就一直存在(在main函數(shù)中初始化). 主線程的runloop :
[NSRunLoop mainRunLoop];其他線程的 Runloop, 需要開發(fā)者自己手動(dòng)去開啟 :
[NSRunLoop currentRunLoop];NSRunloop 既然和線程息息相關(guān), 如果線程銷毀或者 cancel , 則當(dāng)前Runloop結(jié)束工作
NSRunLoop是保證線程不會(huì)退出,并且能在不處理消息的時(shí)候讓線程休眠,節(jié)約資源,在接收到消息的時(shí)候喚醒線程做出對(duì)應(yīng)處理的消息循環(huán)機(jī)制
-
NSRunloop 和 當(dāng)前線程一一對(duì)應(yīng). 例如字典的 鍵值對(duì), 可比喻成:
NSMutableDictionary *dict = [NSMutableDictionary dictionary]; dict[@"mainThread"] = @"[NSRunLoop mainRunLoop]"; dict[@"thread1"] = @"RunLoop1"; dict[@"thread2"] = @"RunLoop2"; dict[@"thread3"] = @"RunLoop3"; dict[@"thread4"] = @"RunLoop4";
二.NSRunloop的本質(zhì)
-
1.NSRunloop 本質(zhì)上就是一個(gè)
do - while循環(huán)do { var message = get_next_message(); process_message(message); } while (message != quit); 2.如果一直存在消息, 則一直循環(huán)去處理 消息,直到消息處理完畢,才跳出循環(huán)
三.NSRunloop的最常見使用 : NSTimer
同學(xué)們都在知道 在控制器中寫入以下代碼, 那么每隔3s都會(huì)執(zhí)行一次指定的方法(這里先不考慮timer和self的引用)
NSTimer *timer = [NSTimer timerWithTimeInterval:3 target:self selector:@selector(excute) userInfo:nil repeats:true];
// 將timer 注冊(cè)到 Runloop中
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
四.NSRunloop的Mode
NSDefaultRunLoopMode : 默認(rèn)的模式
UITrackingRunLoopMode : 當(dāng)滾動(dòng)的時(shí)候會(huì)調(diào)用的模式
NSRunLoopCommonModes : (NSDefaultRunLoopMode 和 UITrackingRunLoopMode的組合)
...

62046-20170508103511988-278243544.png
- 1.
NSRunloop中包含多個(gè)Mode,每個(gè)Mode中包含 :Source(Source0 , Source1)TimerObserver - 2.每個(gè)Mode之間都是相對(duì)獨(dú)立的,當(dāng)切換
Mode時(shí)必須退出當(dāng)前Mode,然后重新進(jìn)入Runloop以保證不同Mode的SourceTimerObserver互不影響。 - 3.實(shí)際運(yùn)用:
NSRunLoopCommonModes運(yùn)用的較多. 原因: 一個(gè)縱向可滾動(dòng)的scrollView上存放著3個(gè)橫向滾動(dòng)的 自動(dòng)滾動(dòng)輪播圖,如果 輪播圖中的timer添加的Mode是NSDefaultRunLoopMode或者UITrackingRunLoopMode,那么我們手動(dòng)拉動(dòng) ScrollView時(shí), 輪播圖是靜止不動(dòng)的,因?yàn)?code>RunLoop只有一個(gè)Mode,無法進(jìn)行切換. 如果添加的是NSRunLoopCommonModes,那么當(dāng)我沒拉動(dòng)scrollView時(shí),RunLoop在這兩種Mode之間不停的切換,保證了輪播圖也可以正常滾動(dòng)