一提起RunLoop感覺很高大尚的樣子,讓我有一種望而生畏的心里,今天翻閱了關(guān)于學習RunLoop的資料,以下做出總結(jié):

- RunLoop的第一個作用
程序啟動的時候系統(tǒng)內(nèi)部會創(chuàng)建RunLoop對象,RunLoop 直到main函數(shù)結(jié)束后程序還可以運行。iOS程序之所以啟動完畢一直保持運行狀態(tài)完全是因為內(nèi)部有一個RunLoop,RunLoop本身就是一個死循環(huán)。RunLoop不退出,程序就不會退出。(不考慮程序異常奔潰或用戶主動殺死程序情況)
- RunLoop的監(jiān)聽事件和傳遞事件
當用戶觸摸或點擊屏幕時,系統(tǒng)底層就會根據(jù)當前用戶觸摸或點擊的位置創(chuàng)建一個事件對象,這個事件對象會經(jīng)過操作系統(tǒng),經(jīng)過對應(yīng)的端口,進入應(yīng)用程序的事件隊列中。一旦有事件進入事件隊列中,RunLoop就會立即作出響應(yīng),并從事件隊列中取出前面的事件,然后將事件對象傳遞給UIApplication對象,UIApplication對象接收到RunLoop傳遞給它的事件對象之后,繼續(xù)將事件對象傳遞下去,查找一個最合適處理事件的對象(UIResponder),找到之后,就可以開始處理事件。這就是事件處理的流程了。最重要的環(huán)節(jié)應(yīng)該是當事件隊列中有事件對象的時候,RunLoop會從事件隊列中取出前面的事件對象,將事件傳遞給UIApplication對象,可以得到如下結(jié)論RunLoop另一重要的作用:監(jiān)聽事件和傳遞事件。沒有RunLoop,任何事件都得不到處理,得不到響應(yīng)。
- RunLoop的其他作用
每個線程內(nèi)部都會默認創(chuàng)建對應(yīng)的RunLoop對象。上面說的RunLoop都是主線程的RunLoop,當然了不管是主線程的RunLoop還是子線程的RunLoop,它們的作用跟剛剛說的是一樣。
針對以上的解釋大家肯定覺得有疑惑,針對幾個問題作出總結(jié):
- RunLoop是一個死循環(huán),它的其中一個作用就是保持應(yīng)用程序不退出。如果我開啟了10個線程,每個線程內(nèi)部有一個RunLoop的話,意味著每一個線程內(nèi)部就有一個死循環(huán),那這樣不就導致線程執(zhí)行完耗時操作之后永遠無法退出,永遠不會被銷毀直到應(yīng)用程序退出,這樣不就導致資源浪費性能差嗎?
每一個線程內(nèi)部都會有對應(yīng)的RunLoop是肯定的,但是默認只有主線程的RunLoop是開啟,而子線程的RunLoop默認是不開啟的。RunLoop不開啟可以理解為死循環(huán)是沒有執(zhí)行的。所以你剛剛說的問題其實不存在的,除了主線程之外,所有子線程在執(zhí)行完對應(yīng)的任務(wù)之后,就會被系統(tǒng)銷毀了。
- 子線程在執(zhí)行完對應(yīng)的任務(wù)之后,就會被系統(tǒng)銷毀了,那主線程什么時候銷毀?
在程序啟動時系統(tǒng)內(nèi)部創(chuàng)建的第一個RunLoop就是主線程的RunLoop呀,為了保證程序不退出,主線程的RunLoop默認就是開啟的。主線程如果退出的話,那就意味著整個程序也退出了
- RunLoop是一個死循環(huán),那它一直在循環(huán)不是很耗性能,很耗電?
If noevents are present and ready to be handled, the run loop puts the thread tosleep.
這句英文的意思是說:如果沒有事件要處理時,RunLoop會讓線程進入睡眠狀態(tài)。在睡眠的時候,消耗性能就非常少了。一旦有事件產(chǎn)生了,RunLoop會立刻喚醒當前線程來響應(yīng)事件。事件處理完畢之后,RunLoop會繼續(xù)循環(huán)檢測事件的到來,如果在一定的時間內(nèi),又沒有事件產(chǎn)生了,RunLoop又會讓線程再次進入睡眠狀態(tài)來節(jié)省性能開銷。
以上只是粗略的總結(jié),繼續(xù)學習!加油