1. RunLoop理解
- RunLoop 就是線程中的一個循環(huán),RunLoop 會在循環(huán)中會不斷檢測,通過 Input sources(輸入源)和 Timer sources(定時源)兩種來源等待接受事件;然后對接受到的事件通知線程進(jìn)行處理,并在沒有事件的時候讓線程進(jìn)行休息。
- RunLoop 實際上是一個對象,這個對象在循環(huán)中用來處理程序運行過程中出現(xiàn)的各種事件(比如說觸摸事件、UI刷新事件、定時器事件、Selector事件),從而保持程序的持續(xù)運行。
- RunLoop 在沒有事件處理的時候,會使線程進(jìn)入睡眠模式,從而節(jié)省 CPU 資源,提高程序性能。
2.RunLoop 和線程
- 一條線程對應(yīng)一個RunLoop對象,每條線程都有唯一一個與之對應(yīng)的 RunLoop 對象。
- RunLoop 并不保證線程安全。我們只能在當(dāng)前線程內(nèi)部操作當(dāng)前線程的 RunLoop 對象,而不能在當(dāng)前線程內(nèi)部去操作其他線程的 RunLoop 對象方法。
- RunLoop 對象在第一次獲取 RunLoop 時創(chuàng)建,銷毀則是在線程結(jié)束的時候。
- 主線程的 RunLoop 對象系統(tǒng)自動幫助我們創(chuàng)建好了,而子線程的 RunLoop對象需要我們主動創(chuàng)建和維護(hù)。
3. RunLoop的相關(guān)類
- CFRunLoopRef:代表 RunLoop 的對象
- CFRunLoopModeRef:代表 RunLoop 的運行模式
- CFRunLoopSourceRef:就是 RunLoop 模型圖中提到的輸入源 / 事件源
- CFRunLoopTimerRef:就是 RunLoop 模型圖中提到的定時源
- CFRunLoopObserverRef:觀察者,能夠監(jiān)聽 RunLoop 的狀態(tài)改變
一個RunLoop對象(CFRunLoopRef)中包含若干個運行模式(CFRunLoopModeRef)。而每一個運行模式下又包含若干個輸入源(CFRunLoopSourceRef)、定時源(CFRunLoopTimerRef)、觀察者(CFRunLoopObserverRef)。
每次 RunLoop 啟動時,只能指定其中一個運行模式(CFRunLoopModeRef),這個運行模式(CFRunLoopModeRef)被稱作當(dāng)前運行模式(CurrentMode)。
如果需要切換運行模式(CFRunLoopModeRef),只能退出當(dāng)前 Loop,再重新指定一個運行模式(CFRunLoopModeRef)進(jìn)入。
這樣做主要是為了分隔開不同組的輸入源(CFRunLoopSourceRef)、定時源(CFRunLoopTimerRef)、觀察者(CFRunLoopObserverRef),讓其互不影響 。
- 系統(tǒng)默認(rèn)注冊了5個Mode常用的有3個:
1.kCFRynLoopDefaultMode:App的默認(rèn)Mode,通常主線程是在這個Mode下運行
2.UITrackingRunLoopMode:界面跟蹤Mode,用于ScrollView追蹤觸摸滑動,保證界面滑動時不受其他Mode影響
3.kCFRunLoopCommonModes:這是一個占位用的Mode,不是一種真正的Mode
4.UIInitializationRunLoopMode:在剛啟動App時進(jìn)入的第一個Mode,啟動完成后不再使用
5.GSEventReceiveRunLoopMode:接受系統(tǒng)事件的內(nèi)部Mode,通常用不到