什么是RunLoop
Runloop視頻
這個視頻講得很好,看完收獲很大屡立,對RunLoop有概念了褂痰,并且了解了一些應(yīng)用亩进。尤其是前面那個子線程timer的例子,一步一步遞進(jìn)缩歪,容易理解归薛,建議多看幾遍。
從這個例子開始了解匪蝙,創(chuàng)建計時器:
主線程添加計時器
上面的scheduledTimerWithTimeInterval是對下面的封裝主籍。是添加到NSRunLoop的默認(rèn)模式,還是要用下面的方式創(chuàng)建加timer逛球。
子線程添加計時器
- 一條線程的生命只能由它的任務(wù)保住千元,讓線程有執(zhí)行不完的任務(wù),線程就不會釋放了颤绕。
- 一條線程上面的RunLoop默認(rèn)是不循環(huán)的幸海,要手動run起來。[[NSRunLoop currentRunLoop] run]死循環(huán)奥务,和while(true)一樣物独,但是更多內(nèi)容。
- 執(zhí)行currentRunLoop() 第一次獲取RunLoop的時候才創(chuàng)建氯葬,屬于懶加載挡篓。
-
暴力退出線程 [NSThread exit];
CFRunLoopRun的偽代碼 Runloop培訓(xùn)視頻有講解
兩小時二十五分鐘開始聽比較好。
__CFRunLoopRun {
do {
__CFRunLoopDoBlocks 處理 block
__CFRunLoopDoSources0 處理 source0
if (判斷是否有其他消息需要處理帚称,如果有) {
goto: handler_msg(處理消息模塊)
}
__CFRunLoopServiceMachPort(wait) 準(zhǔn)備休眠 阻塞 // 如果有消息來了官研,需要處理就醒了
handle_msg: (處理消息模塊:timer, gcd, __CFRunLoopDoSource1)
} while(1)
}
從字面上看
- 運行循環(huán)
- 跑圈
基本作用
- 保持程序的持續(xù)運行(比如主運行循環(huán))
- 處理APP中的各種事件(比如觸摸事件秽澳、定時器事件、Selector事件)
- 節(jié)省CPU資源戏羽,提高程序性能:該做事時做事肝集,該休息時休息
存在價值
RunLoop 對象
- iOS中有兩套API來訪問和使用RunLoop
1. Foundation(NSRunLoop)
2. Core Foundation(CFRunLoopRef) - NSRunLoop 和 CFRunLoopRef 都代表著 RunLoop 對象
- NSRunLoop 是基于 CFRunLoopRef 的一層OC包裝,所以要了解 RunLoop 內(nèi)部結(jié)構(gòu)蛛壳,多研究 CFRunLoopRef 層面的 API(CoreFoundation層面)
RunLoop 與多線程
- 每條線程都有唯一的一個與之對應(yīng)的 RunLoop 對象
- 主線程的RunLoop 已經(jīng)自動創(chuàng)建好了,子線程的 RunLoop 需要主動創(chuàng)建
- RunLoop 在第一次獲取時創(chuàng)建所刀,在線程結(jié)束時銷毀
獲取 RunLoop 對象
- Foundation
[NSRunLoop currentRunLoop]; // 獲取當(dāng)前線程的 RunLoop 對象
[NSRunLoop mainRunLoop]; // 獲得主線程的 RunLoop 對象
- Core Foundation
CFRunLoopGetCurrent(); // 獲得當(dāng)前線程的RunLoop 對象
CFRunLoopGetMain(); // 獲得主線程的 RunLoop 對象
RunLoop相關(guān)類
- Core Foundation 中關(guān)于 RunLoop 的5個類
- CFRunLoopRef
- CFRunLoopModeRef
- CFRunLoopSourceRef
- CFRunLoopTimerRef
- CFRunLoopObserveRef
注:RunLoop如果沒有這些東西衙荐,會直接退出
RunLoop 應(yīng)用
- 常駐線程
- NSTimer
- 自動釋放池
- PerformSelector
- ImageView 顯示
1. 常駐線程
應(yīng)用場景:經(jīng)常在后臺進(jìn)行耗時操作,比如:監(jiān)控聯(lián)網(wǎng)狀態(tài)浮创,掃描沙盒等忧吟,不希望線程處理完事件就銷毀,保持常駐狀態(tài)斩披。
第一種
// 開啟
- (void)run
{
// addPort: 添加端口(就是source)forMode: 設(shè)置模式
[[NSRunLoop currentRunLoop] addPort: [NSPort port] forMode: NSDefaultRunLoopMode];
// 啟動RunLoop
[[NSRunLoop currentRunLoop] run];
/*
//另外兩種啟動方式
[NSDate distantFuture]:遙遠(yuǎn)的未來 這種寫法跟上面的run是一個意思
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
不設(shè)置模式
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate distantFuture]];
*/
}
// 退出當(dāng)前線程
[NSThread exit];
2. NSTimer (最常見 RunLoop 使用)
- (void)timer
{
NSTimer *timer = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
// 定時器只運行在NSDefaultRunLoopMode下溜族,一旦RunLoop進(jìn)入其他模式,這個定時器就不會工作
// [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
// 定時器只運行在UITrackingRunLoopMode下垦沉,一旦RunLoop進(jìn)入其他模式煌抒,這個定時器就不會工作
// [[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];
// 定時器會跑在標(biāo)記為common modes的模式下
// 標(biāo)記為common modes的模式:UITrackingRunLoopMode和NSDefaultRunLoopMode兼容
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}
- (void)timer2
{
// 調(diào)用了scheduledTimer返回的定時器,已經(jīng)自動被添加到當(dāng)前runLoop中厕倍,而且是NSDefaultRunLoopMode
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
// 修改模式
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}
UITableView 滾動時模式由 NSDefaultRunLoopMode 進(jìn)入 UITrackingRunLoopMode寡壮,NSTimer 不再響應(yīng)。NSRunLoopCommonMode模式下兩種模式都可運行讹弯。
3. 自動釋放池
參見參考文章
main里面有個死循環(huán)就是RunLoop循環(huán)
目的:
- 保證程序不退出况既;
- 負(fù)責(zé)監(jiān)聽事件,觸摸(有沒有人摸我)组民、時鐘棒仍、網(wǎng)絡(luò)事件(回調(diào));
- 如果沒有時間發(fā)生臭胜,會讓程序進(jìn)入休眠狀態(tài)莫其;
- 五種模式,UI模式優(yōu)先級最高耸三,UI模式只能被觸摸事件觸發(fā)榜配,保證高效。
- 一條線程的生命只能通過任務(wù)保住
子線程里面設(shè)置定時器吕晌,可以看出子線程里面RunLoop需要自己開啟蛋褥,主線程則默認(rèn)已經(jīng)開啟。直接用while(true)并不能實現(xiàn)觸發(fā)事件效果睛驳。線程的聲明需要通過任務(wù)保住烙心,所以要將RunLoop開啟膜廊。
RunLoop是懶加載,只有第一次去拿才會創(chuàng)建淫茵。
總結(jié)一下
參考文章
https://blog.ibireme.com/2015/05/18/runloop/
深入理解RunLoop
解密-神秘的 RunLoop
(最全)RunLoop 原理+使用場景+面試總結(jié)
學(xué)習(xí)視頻
Runloop視頻 密碼:ztaf
Runloop培訓(xùn)視頻