1、什麼是runLoop程序員
一、說白了,runloop就是運行循環網絡
二、runloop,他是多線程的法寶多線程
一般來說,一個線程一次只能執行一個任務,執行完以後就退出線程。可是,對於主線程是不能退出的,所以咱們須要讓主線程即便任務執行完畢,也能夠繼續等待接收事件而不退出,那麼runloop就能夠作到。異步
可是非主線程一般來講就是爲了執行某一任務的,執行完畢就須要歸還資源,所以默認是不運行runloop的。函數
三、每個線程對應都有一個runloop,只是默認只有主線程的runloop是開啓的,其餘子線程的runloop是默認不啓動的,若要啓動須要程序員手動啓動。oop
2、runloop做用性能
一、保證程序不退出 .net
二、負責監聽全部的事件(sources、observe、timer)(觸摸、時鐘、網絡事件)線程
三、runloop很是懶,有任務就處理,沒有就睡眠設計
四、runloop負責在一次循環中渲染UI
3、runloop模式
NSRunLoopDefaultMode:
App的默認Mode,一般主線程是在這個Mode下運行
UITrackingRunLoopMode:處理UI事件的mode
NSRunLoopCommonModes:
這是一個佔位用的Mode,不是一種真正的Mode(默認在NSRunLoopDefaultMode和UITrackingRunLoopMode這兩種模式下)
UIInitializationRunLoopMode:
在剛啓動App時進入的第一個Mode,啓動完成後再也不使用
GSEventReceiveRunLoopMode:
接受系統事件的內部Mode,一般用不到
一個場景:加載多張高清大圖時拖拽tableView,致使界面卡頓
分析一:
加載多張高清大圖:須要加入runloop,在運行循環時渲染UI,進入UITrackingRunLoopMode模式
拖拽tableView:須要加入runloop,在運行循環時處理觸摸事件,進入UITrackingRunLoopMode模式
加載多張高清大圖,至關於runloop一次循環渲染了多張大圖(多個任務),佔用了此次循環的大部分時間,致使界面卡頓
解決方案:讓runloop一次循環只渲染一張大圖(只幹一件事),定義觀察者,每次循環添加一張圖片進行渲染!
代碼以及實現已經有大神整理好了:https://blog.csdn.net/liyanjun201/article/details/79096289
如下是其餘大神整理的關於runloop的資料 很全面 https://blog.csdn.net/qq_30513483/article/details/53373905
RunLoop是什麼,有什麼做用,如何獲取?
- 定義
- RunLoop的實質是一個死循環,用於保證程序的持續運行,只有當程序退出的時候纔會結束(由main函數開啓主線程的RunLoop)
- 做用
- 保持程序的持續運行
- 處理App中的各類事件(觸摸、定時器、Selector事件)
- 節省CPU資源,提升程序性能(該作事作事,沒事作休息)
- 獲取方法
- 使用NSRunLoop(面向對象)或者CFRunLoopRef(底層C語言)
RunLoop的原理
- RunLoop開啓一個循環事件,並接受輸入事件,接受的事件來自兩種不一樣的來源:
- 輸入源(input source)(傳遞異步事件)
- 定時源(timer source)(傳遞同步事件)
- RunLoop接收到消息後採用handlePort、customSrc、mySelector和timerFired等四個方法處理對應的事件
- 當RunLoop沒有接收到消息時,則進入休眠狀態,以保持程序持續運行
RunLoop的原理
RunLoop接收幾種輸入源,系統默認定義了幾種模式?
- 輸入源有兩種
- 基於端口的輸入源(port)
- 自定義的輸入源(custom)
- 系統定義的RunLoop模式有五種,最經常使用的有三種,以下所示:
- NSDefaultRunLoopMode
- 默認模式,主線程中默認是NSDefaultRunLoopMode
- UITrackingRunLoopMode
- NSRunLoopCommonModes
- 並非真正意義上的Mode,是一個佔位用的「Mode」,默認包含了NSDefaultRunLoopMode和UITrackingRunLoopMode兩種模式
RunLoop模式的原理和使用注意點?
- 原理和注意點
- 一個RunLoop包含若干個Mode,每一個Mode又包含若干個Source、Observer、Timer(以下圖所示)
- 每次RunLoop啓動,只能指定一個Mode,這個Mode被稱爲CurrentMode
- 若是須要切換Mode,只能退出Loop,再從新指定一個Mode進入, 以使不一樣組之間的Source、Observer、Timer互不受影響
RunLoopMode
RunLoop和線程有什麼關係
- RunLoop與線程是一一對應的
- 程序啓動時,主線程默認會本身建立RunLoop,並設置爲Default模式
- 建立子線程時,必須獲取當前線程的RunLoop並啓動它
NSTimer和RunLoop的關係?
- NSTimer須要添加到Runloop中, 才能執行的狀況
- NSTimer默認被添加到Runloop中, 直接執行的狀況
NSTimer準確嗎,若是不許確,如何設計一個準確的timer?
- 不許確
- 準確的Timer應該和當前線程的RunLoopMode保持一致
TableView/ScrollView/CollectionView滾動時爲何NSTimer會中止?
- 一個RunLoop不能同時共存兩個mode
- 當滾動視圖滾動時,當前RunLoop處於UITrackingRunLoopMode,
- NSTimer的RunLoopMode和當前線程的RunLoopMode不一致,因此會中止
- 解決方法:將timer的runloopMode改成UITrackingRunLoopMode或者NSRunLoopCommonModes
若是NSTimer在分線程中建立,會發生什麼,應該注意什麼?
- NSTimer沒有啓動
- 在主線程中,系統默認建立並啓動主線程的runloop
- 在分線程中,系統不會自動啓動runloop,須要手動啓動
- 解決方法:
在異步線程中下載不少圖片,若是失敗了,該如何處理?請結合RunLoop來談談解決方案
- 在異步線程中啓動一個RunLoop從新發送網絡請求,下載圖片
若是程序啓動就須要執行一個耗時操做,你會怎麼作?
- 開啓一個異步的子線程,並啓動它的RunLoop來執行該耗時操做
runloop與autoreleasepool的關係
若是在分線程中啓動一個異步請求,會有什麼問題?
判斷其是否請求結束,若是未結束,要保持當前線程一直啓動,直到結束
程序啓動時,runloop是如何工做的?若是程序啓動就須要執行一個耗時操做,你會怎麼作?
程序啓動時,系統默認建立並啓動主線程的runloop,runloop會默認建立兩個Observe來進行監聽runloop的進出和睡眠,有事情的時候就去作,沒事的休眠
(線程(建立)-->runloop將進入-->最高優先級OB建立釋放池-->runloop將睡-->最低優先級OB銷燬舊池建立新池-->runloop將退出-->最低優先級OB銷燬新池-->線程(銷燬))
線程剛建立時並無runloop,若是你不主動去獲取,那麼一直都不會有。
耗時操做能夠放在分線程中進行,結束後回到主線程