1、RunLoop是什麼?
RunLoop是運行循環,在程序運行過程中循環做一些事情,如果沒有RunLoop:程序執行完畢就會立即退出;如果有RunLoop:程序會一直運行,並且時時刻刻在等待用戶的輸入操作。RunLoop可以再需要的時候自己跑起來運行,在沒有操作的時候停下來休息。充分節省CPU資源,提要程序性能。
iOS將RunLoop封裝成一個對象,每條線程都有與之對應的runloop,主線程的runloop已經創建好,子線程的需要自己創建~
2、RunLoop的基本作用?
1)保持程序運行:程序一啓動就會開一個主線程,主線程一開起來就會跑一個主線程對應的RunLoop,RunLoop保證主線程不會被銷燬,也就保證了程序的持續運行
2)處理App的各種事件(比如:觸摸事件,定時器事件,Selector事件等)
3)節省CPU資源,提高性能:程序運行起來時,當什麼操作都沒有做的時候,RunLoop就告訴CUP,現在沒有事情做,我要去休息,這時CPU就會將其資源釋放出來去做其他的事情,當有事情做的時候RunLoop就會立馬起來去做事情
3、RunLoop的原理
等待消息 接收消息 處理消息 循環
有任務的時候處理任務,沒有任務的時候休眠
這個對象管理着其需要處理的事件和消息,並提供了Loop Event的函數入口。
線程進入了這個函數後,就會一直處理函數內部 “接受消息 -> 等待 -> 處理” 的循環中。
直到這個循環結束(比如傳入quit消息),函數返回。
他在沒有消息處理的時候休眠,有消息處理的時候立刻被喚醒。
4、RunLoop對象
OSX/iOS 系統中,提供了兩個這樣的對象:NSRunLoop 和 CFRunLoopRef。
CFRunLoopRef 是在 CoreFoundation 框架內的,它提供了純 C 函數的 API,所有這些 API 都是線程安全的。
NSRunLoop 是基於 CFRunLoopRef 的封裝,提供了面向對象的 API,但是這些 API 不是線程安全的。
5、RunLoop的模式:
1. Default:kCFRunLoopDefaultMode,默認模式,通常主線程是在這個Mode下運行
2. Tracking:UITrackingRunLoopMode:界面跟蹤模式,用於 ScrollView 追蹤觸摸滑動,保證界面滑動時不受其他 Mode 影響
3. Initialization:UIInitializationRunLoopMode: 在剛啓動 App 時第進入的第一個 Mode,啓動完成後就不再使用
4. EventReceive:GSEventReceiveRunLoopMode: 接受系統事件的內部 Mode,通常用不到 ?????
5. kCFRunLoopCommonModes: 這是一個組合Mode,作爲標記kCFRunLoopDefaultMode和UITrackingRunLoopMode用,並不是一種真正的Mode
6、NSTimer在頁面滑動時就暫停計時:
原因:當NStimer調用 scheduledTimerWithTimeInterval 時候, 生成的timer對象的RunLoop的模式是 NSDefaultRunLoopModes 模式
但是當前頁面如果有scrollView滾動時,當前線程RunLoop模式就會變成NSEventTrackingRunLoopModes, timer就無法循環執行了
處理:如果想要timer不受影響,那麼我們需要把timer的RunLoop模式改成組合模式 NSRunLoopCommonModes 模式
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];