runloop


使用范例

-(NSThread *)networkRequestThread{

//單例創(chuàng)建線程對(duì)象

static NSThread *networkRequestThread;

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

//創(chuàng)建的同時(shí)啟動(dòng)該線程runloop

networkRequestThread = [[NSThread alloc]initWithTarget:self selector:@selector(networkRequestThreadEntryPoint:) object:nil];

[networkRequestThread start];

});

return networkRequestThread;

}

//線程入口

-(void) networkRequestThreadEntryPoint:(id)__unused object{

//自動(dòng)釋放池,保證里面的autorelease對(duì)象能夠在出了作用范圍外就可以自動(dòng)釋放,而不是一直等到runloop結(jié)束

@autoreleasepool {

[[NSThread currentThread] setName:@"AFNetworking"];

//獲取當(dāng)前線程runloop

NSRunLoop *currentRunloop = [NSRunLoop currentRunLoop];

//給runloop添加一個(gè)端口作為輸入源,用于線程間通信

[currentRunloop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];

[currentRunloop run];

}

}


使用runloop情景:

開啟一個(gè)常駐線程,能夠保持長時(shí)間去處理各種事件。

NSTimer CADisplayLink 通過向Runloop注冊(cè)來開啟定時(shí)任務(wù)

GCD的延時(shí)操作,UI界面刷新,響應(yīng)用戶的觸摸事件



addPort:{NSMMachPort port】這里將輸入源端口添加到runloop里,通過輸入源端口相當(dāng)于一個(gè)載體,用于進(jìn)行線程間消息的傳遞。

線程間通信方式:通過NSMachPort端口

將端口添加到當(dāng)前線程的runloop里,在runloop的消息循環(huán)機(jī)制中去接受通過端口傳遞過來的消息。也可以通過端口去給其他線程發(fā)送消息。


RunLoop只能運(yùn)行在一種mode下,如果要換mode,當(dāng)前的loop也需要停下重啟成新的。利用這個(gè)機(jī)制,ScrollView滾動(dòng)過程中NSDefaultRunLoopMode(kCFRunLoopDefaultMode)的mode會(huì)切換到UITrackingRunLoopMode來保證ScrollView的流暢滑動(dòng):只能在NSDefaultRunLoopMode模式下處理的事件會(huì)影響scrllView的滑動(dòng)。

如果我們把一個(gè)NSTimer對(duì)象以NSDefaultRunLoopMode(kCFRunLoopDefaultMode)添加到主運(yùn)行循環(huán)中的時(shí)候, ScrollView滾動(dòng)過程中會(huì)因?yàn)閙ode的切換,而導(dǎo)致NSTimer將不再被調(diào)度。

同時(shí)因?yàn)閙ode還是可定制的,所以:

Timer計(jì)時(shí)會(huì)被scrollView的滑動(dòng)影響的問題可以通過將timer添加到NSRunLoopCommonModes(kCFRunLoopCommonModes)來解決。

1、如果是在主線程中運(yùn)行timer,想要timer在某界面有視圖滾動(dòng)時(shí),依然能正常運(yùn)轉(zhuǎn),那么將timer添加到RunLoop中時(shí),就需要設(shè)置mode 為NSRunLoopCommonModes。

2、如果是在子線程中運(yùn)行timer,那么將timer添加到RunLoop中后,Mode設(shè)置為NSDefaultRunLoopMode或NSRunLoopCommonModes均可,但是需要保證RunLoop在運(yùn)行,且其中有任務(wù)。


偽代碼

function loop() {

initialize();

do {

var message = get_next_message();

process_message(message);

} while (message != quit);

}


CADisplayLink是一個(gè)能讓我們以和屏幕刷新率同步的頻率將特定的內(nèi)容畫到屏幕上的定時(shí)器類

CADisplayLink以特定模式注冊(cè)到runloop后,每當(dāng)屏幕顯示內(nèi)容刷新結(jié)束的時(shí)候,runloop就會(huì)向CADisplayLink指定的target發(fā)送一次指定的selector消息,CADisplayLink類對(duì)應(yīng)的selector就會(huì)被調(diào)用一次。




22.runloop和線程有什么關(guān)系

runloop與線程是一一對(duì)應(yīng)的

對(duì)于主線程來說,runloop在默認(rèn)啟動(dòng)的。

對(duì)于子線程來說,runloop是懶加載的,只有當(dāng)我們手動(dòng)獲取的時(shí)候才會(huì)創(chuàng)建。

當(dāng)線程的 runloop 被打開后就能保持著接受并處理各種消息,而不會(huì)中途退出(有任務(wù)就去接受處理,沒有就處于休眠狀態(tài))。


23.runloop的mode作用是什么

model 按照優(yōu)先級(jí)可分為:

NSDefaultRunLoopMode(kCFRunLoopDefaultMode):默認(rèn),通常主線程在這個(gè) Mode 下運(yùn)行

UITrackingRunLoopMode:保證Scrollview滑動(dòng)順暢

UIInitializationRunLoopMode:?jiǎn)?dòng)程序后的過渡mode,啟動(dòng)完成后就不再使用

NSRunLoopCommonModes :占位mode,可以向其中添加其他mode


24.以+ scheduledTimerWithTimeInterval...的方式觸發(fā)的timer,在滑動(dòng)頁面上的列表時(shí),timer會(huì)暫定回調(diào),為什么?如何解決

(RunLoop只能運(yùn)行在一種mode下,切換mode的時(shí)候runloop會(huì)有一個(gè)重啟的動(dòng)作。

ScrollView滾動(dòng)過程中NSDefaultRunLoopMode的mode會(huì)切換到UITrackingRunLoopMode來保證ScrollView的流暢滑動(dòng)。NSTimer 對(duì)象默認(rèn)是以NSDefaultRunLoopMode注冊(cè)到runloop里的,所以切換的時(shí)候?qū)е翹STimer將不再被調(diào)度。所以需要將NSTimer以 NSRunLoopCommonModes 的方式注冊(cè)到Runloop中才能保持一致調(diào)用。)



RunLoop 理解成下面循環(huán)

1.休眠狀態(tài)

2.接收到要處理的消息,被喚醒

3.對(duì)消息進(jìn)行處理

4.消息處理完畢之后,回到休眠狀態(tài)

1(等待消息) -> 2(將要處理消息) -> 3(處理消息) -> 4(消息處理完成) -> 1(等待消息)

對(duì)于每一個(gè) runloop 系統(tǒng)會(huì)默認(rèn)為期創(chuàng)建一個(gè)自動(dòng)釋放池。

AutoreleasePool 在 4 (消息處理完成) 這個(gè)階段進(jìn)行釋放。iOS 開發(fā)者寫的程序,無論包含多少層函數(shù)調(diào)用,也一直處于 3 (處理消息) 這個(gè)階段當(dāng)中,其余階段屬于 UI 框架的一部分。因此在當(dāng)前消息循環(huán)內(nèi),放到 AutoreleasePool 的對(duì)象會(huì)一直生效,并不會(huì)被釋放


入口函數(shù)作用

- 初始化UIApplication單例對(duì)象

-?初始化AppDelegate對(duì)象,并設(shè)為UIApplication對(duì)象的代理

-?建立一個(gè)主事件循環(huán),其中包含UIApplication的Runloop來開始處理事件。


runloop退出的條件:app退出;線程關(guān)閉;



當(dāng)我們?nèi)?dòng) RunLoop,系統(tǒng)會(huì)自動(dòng)在內(nèi)部創(chuàng)建自動(dòng)釋放池。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 原文地址:http://blog.ibireme.com/2015/05/18/runloop/ RunLoop ...
    大餅炒雞蛋閱讀 1,273評(píng)論 0 6
  • 深入理解RunLoop 由ibireme| 2015-05-18 |iOS,技術(shù) RunLoop 是 iOS 和 ...
    橙娃閱讀 980評(píng)論 1 2
  • http://www.cocoachina.com/ios/20150601/11970.html RunLoop...
    紫色冰雨閱讀 955評(píng)論 0 3
  • 轉(zhuǎn)自http://blog.ibireme.com/2015/05/18/runloop 深入理解RunLoop ...
    飄金閱讀 1,094評(píng)論 0 4
  • 放假回家,下飛機(jī)的時(shí)候,無意間碰見了揚(yáng)子,他從頭等艙出來,我在經(jīng)濟(jì)艙出來,相遇時(shí)在空氣中除了彌漫著老同學(xué)相見的喜悅...
    x青爭(zhēng)閱讀 961評(píng)論 2 3

友情鏈接更多精彩內(nèi)容