APP啟動時運行main函數,main函數里面啟動了RunLoop,然后這個RunLoop一直跑圈就像do····while(YES)死循環那樣,程序一直保持運行狀態,時刻準備處理App的各種事件(例如觸摸事件、定時器事件、Selector事件)。一條線程對應一個RunLoop對象且生死同步。NSTimer的固定頻率執行方法本質上就是定時輸入事件到RunLoop,PerformSelector也是產生事件輸入源輸入到RunLoop之中。
main函數
訪問RunLoop對象
- Foundation框架NSRunLoop類(CFRunLoopRef的OC包裝)
// 獲得當前線程的RunLoop對象
[NSRunLoop currentRunLoop];
// 獲得主線程的RunLoop對象
[NSRunLoop mainRunLoop];
- Core Foundation框架CFRunLoopRef類
// 獲得當前線程的RunLoop對象
CFRunLoopGetCurrent();
// 獲得主線程的RunLoop對象
CFRunLoopGetMain();
RunLoop其他類
- RunLoop的運行模式類:CFRunLoopModeRef
一個 RunLoop 包含若干個 Mode,每個Mode又包含若干個Source/Timer/Observer;
每次RunLoop啟動時,只能指定其中一個 Mode,這個Mode被稱作 CurrentMode;
如果需要切換Mode,只能退出Loop,再重新指定一個Mode進入;
這樣做主要是為了分隔開不同組的Source/Timer/Observer,讓其互不影響。
> 系統默認注冊了5個Mode:
kCFRunLoopDefaultMode:App的默認Mode,通常主線程是在這個Mode下運行
UITrackingRunLoopMode:界面跟蹤Mode,用于ScrollView 追蹤觸摸滑動,保證界面滑動時不受其Mode影響
UIInitializationRunLoopMode: 在剛啟動 App 時第進入的第一個 Mode,啟動完成后就不再使用
GSEventReceiveRunLoopMode: 接受系統事件的內部 Mode,通常用不到
kCFRunLoopCommonModes: 這是一個占位用的Mode,不是一種真正的Mode,只有把NSTimer的runloop model切換成這個模式才能夠保證及時用戶拖動TableView系統進入UITrackingRunLoopMode不被中斷。
- RunLoop的事件輸入源類:CFRunLoopSourceRef
Port-Based Sources
Custom Input Sources
Cocoa Perform Selector Sources
Source0:非基于Port的
Source1:基于Port的
- RunLoop的時間觸發器類:CFRunLoopTimerRef
類似于NSTimer不斷計時然后條件觸發事件
- RunLoop的觀察者類:CFRunLoopObserverRef
監聽RunLoop的狀態改變
RunLoop處理邏輯
事件輸入源
RunLoop處理邏輯
RunLoop時序