iOS RunLoop
發(fā)布時間:2016/03/20 10:21
閱讀:68
收藏:2
點(diǎn)贊:2
什么是RunLoop?RunLoop到底有多神秘,多神奇,????RunLoop是怎么工作的,有什么用,今天就來帶大家簡略的刨根問底一下。
當(dāng)一個App啟動,如果我們不做任何交互操作,那么App默認(rèn)不會做任何響應(yīng),一旦我們觸摸了屏幕,或點(diǎn)擊了某個按鈕,程序就立即做出相應(yīng)的響應(yīng),給我們的操作一個反饋。
仿佛這個app是處于一個時刻準(zhǔn)備著的狀態(tài),沒人干活的時候就休息,有人操作了就做出響應(yīng),這一切終究歸于一個叫RunLoop的東西。Run -> 運(yùn)行,Loop -> 循環(huán),RunLoop就是一個運(yùn)行循環(huán)。那什么才是運(yùn)行循環(huán)呢?在iOS中RunLoop又充當(dāng)一個什么樣的角色呢?
其實在App中,所有的事件響應(yīng)都由運(yùn)行循環(huán)來派發(fā)和調(diào)度,當(dāng)用戶沒有任何操作時,運(yùn)行循環(huán)處于休眠狀態(tài),一旦用戶點(diǎn)擊了,或者觸摸了屏幕某個地方,運(yùn)行循環(huán)會立即蘇醒,來找到最佳響應(yīng)者(這里涉及到響應(yīng)者鏈條,后續(xù)會繼續(xù)說明),然后處理這個事件。
優(yōu)點(diǎn):
因為有了運(yùn)行循環(huán)的存才,不需要app一直除以活躍狀態(tài),一切由RunLoop來監(jiān)管,這樣大大節(jié)省了系統(tǒng)資源。
RunLoop與線程的關(guān)系:
程序啟動會后,會執(zhí)行main方法,設(shè)置AppDelegate,并且會為主線程設(shè)置RunLoop并默認(rèn)啟動,這就是為什么程序啟動,就能響應(yīng)操作的原因。
而當(dāng)我們開啟子線程的時候,子線程的運(yùn)行循環(huán)默認(rèn)不開啟,這是因為除了主線程以外,并不是線程開的越多越好,當(dāng)子線程工作完成,出于一個空閑狀態(tài)時,這個線程會被底層線程池回收,而如果子線程的RunLoop默認(rèn)是開啟的,那么這個子線程永遠(yuǎn)釋放不掉,反而導(dǎo)致性能下降,所以,為什么主線程的運(yùn)行循環(huán)默認(rèn)啟動,而子線程的運(yùn)行循環(huán)默認(rèn)不啟動,大家應(yīng)該能夠了解了。
RunLoop內(nèi)部:掛一張任何帖子都看得到的圖

RunLoop內(nèi)部有一個輸入源(input sources),一個定時源(Timer sources)
1. 輸入源:傳遞異步事件,消息通常來自與其他線程,處理其他線程的消息,比如:下載操作執(zhí)行完畢,要回到主線程個更新UI,這些異步事件,就是有RunLoop來監(jiān)聽和管理
2. 定時源:傳遞同步事件,發(fā)生在特定時間,或者時間間隔,比如:定時檢查UI界面上有沒有刷新事件,點(diǎn)擊時間等等,也就是處理本線程上的事件
運(yùn)行循環(huán)共有5總模式:
1. NSDefaultRunLoopMode:是RunLoop默認(rèn)的模式,表示程序空閑。如果我們用NSTimer來每個一秒鐘打印輸出的時候,一旦有手勢操作(例如滑動,滾動操作),那么NSTimer就會停止打印。所以這是RunLoop默認(rèn)的模式。
2. UITrackingRunLoopMode:跟蹤模式(是ScrollView專用的模式),上面第一條所說的,一旦有滾動,滑動類似的操作,RunLoop就會默認(rèn)由NSDefaultRunLoopMode模式切換到UITrackingRunLoopMode模式,目的就是為了保證滑動的流暢性,給用戶提供流暢的體驗。
3. NSRunLoopCommonMode:這種模式會包含以上兩種模式,我們滑動操作的同時,NSTimer時鐘調(diào)用的方法也會被執(zhí)行(也會打印出來結(jié)果),但是,一旦所調(diào)用的方法中,有耗時操作,當(dāng)我們再次滑動時,效果簡直卡到爆。
所以,再實際開發(fā)中,不建議講RunLoop的模式更改為NSRunLoopCommonMode。
但是,有的需求就是又要做耗時操作,又想有流暢滑動效果,那么OK,將耗時操作放在后臺,將時鐘操作放在子線程(注意:子線程RunLoop需要手動開啟:CFRunLoopRun(),CFRunLoopStop(CFRunLoopCurrent())停止運(yùn)行循環(huán));
4. UIInitializationRunLoopMode:在程序剛剛啟動時進(jìn)入的第一個模式,啟動完成就不再使用。
5. GSEventReceiveRunLoopMode:接收系統(tǒng)事件的內(nèi)部mode,通常用不到。
RunLoop應(yīng)用場景:
1. 滑動與刷新
2. 常駐子線程
保持子線程長期運(yùn)轉(zhuǎn)而不被銷毀,可以在子線程手動開啟RunLoop
3. NSURLConnection的下載
NSURLConnection的下載操作默認(rèn)是在主線程的(所有早就了ASI與AFN框架,iOS主推NSURLSession),為了不影響主線程UI操作,將下載任務(wù)放在子線程,就需要手動開啟RunLoop
原文地址:http://www.cocoachina.com/bbs/read.php?tid-1484418.html