深刻淺出 RunLoop(一):初識
深刻淺出 RunLoop(二):數據結構
深刻淺出 RunLoop(三):事件循環機制
深刻淺出 RunLoop(四):RunLoop 與線程
深刻淺出 RunLoop(五):RunLoop 與 NSTimer
深刻淺出 RunLoop(六):相關面試題面試
RunLoop
對象的底層就是一個CFRunLoopRef
結構體,它裏面存儲着:數據結構
RunLoop
與線程是一一對應關係Source0
/Source1
/Timer
/Observer
RunLoop
當前的運行模式RunLoop
全部的 Mode(CFRunLoopModeRef
)模式typedef struct __CFRunLoop * CFRunLoopRef;
struct __CFRunLoop {
pthread_t _pthread; // 與線程一一對應
CFMutableSetRef _commonModes;
CFMutableSetRef _commonModeItems;
CFRunLoopModeRef _currentMode;
CFMutableSetRef _modes;
...
};
複製代碼
CFRunLoopModeRef
表明RunLoop
的運行模式;RunLoop
包含若干個 Mode,每一個 Mode 又包含若干個Source0
/Source1
/Timer
/Observer
;RunLoop
啓動時只能選擇其中一個 Mode,做爲 currentMode;Source0
/Source1
/Timer
/Observer
能分隔開來,互不影響;Source0
/Source1
/Timer
/Observer
,RunLoop
會立馬退出。typedef struct __CFRunLoopMode *CFRunLoopModeRef;
struct __CFRunLoopMode {
CFStringRef _name; // mode 類型,如:NSDefaultRunLoopMode
CFMutableSetRef _sources0; // CFRunLoopSourceRef
CFMutableSetRef _sources1; // CFRunLoopSourceRef
CFMutableArrayRef _observers; // CFRunLoopObserverRef
CFMutableArrayRef _timers; // CFRunLoopTimerRef
...
};
複製代碼
ModeName | 描述 |
---|---|
KCFRunLoopDefaultMode / NSDefaultRunLoopMode | 默認模式 |
UITrackingRunLoopMode | 界面追蹤模式,用於 ScrollView 追蹤觸摸滑動,保證界面滑動時不受其餘 Mode 影響; |
KCFRunLoopCommonModes / NSRunLoopCommonModes | 通用模式(默認包含 KCFRunLoopDefaultMode 和 UITrackingRunLoopMode) 該模式不是實際存在的一種模式,它只是一個特殊的標記,是同步 Source0 /Source1 /Timer /Observer 到多個 Mode 中的技術方案。被標記爲通用模式的Source0 /Source1 /Timer /Observer 都會存放到 _commonModeItems 集合中,會同步這些Source0 /Source1 /Timer /Observer 到多個 Mode 中。 |
RunLoop
運行在 Mode1 下面的時候,是處理不了 Mode2 的事件的;NSDefaultRunLoopMode
默認模式和UITrackingRunLoopMode
滾動模式,滾動屏幕的時候就會切換到滾動模式,就不用去處理默認模式下的事件了,保證了 UITableView 等的滾動順暢。Source0
到RunLoop
並不會主動喚醒線程,須要手動喚醒)performSelector:onThread:
Source1
來處理,而後再交給Source0
處理CFRunloopTimer
和NSTimer
是 toll-free bridged 的,能夠相互轉換;performSelector:withObject:afterDelay:
方法會建立timer
並添加到RunLoop
中。struct __CFRunLoopTimer {
CFRuntimeBase _base;
uint16_t _bits;
pthread_mutex_t _lock;
CFRunLoopRef _runLoop; // 添加該 timer 的 RunLoop
CFMutableSetRef _rlModes; // 全部包含該 timer 的 modeName
CFAbsoluteTime _nextFireDate;
CFTimeInterval _interval; /* immutable */ // 理想時間間隔
CFTimeInterval _tolerance; /* mutable */ // 時間誤差
uint64_t _fireTSR; /* TSR units */
CFIndex _order; /* immutable */
CFRunLoopTimerCallBack _callout; /* immutable */
CFRunLoopTimerContext _context; /* immutable, except invalidation */
};
複製代碼
CFRunLoopObserverRef
用來監聽RunLoop
的 6 種狀態/* Run Loop Observer Activities */
typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
kCFRunLoopEntry = (1UL << 0), // 即將進入 RunLoop
kCFRunLoopBeforeTimers = (1UL << 1), // 即將處理 Timers
kCFRunLoopBeforeSources = (1UL << 2), // 即將處理 Sources
kCFRunLoopBeforeWaiting = (1UL << 5), // 即將進入休眠
kCFRunLoopAfterWaiting = (1UL << 6), // 剛從休眠中喚醒
kCFRunLoopExit = (1UL << 7), // 即將退出 RunLoop
kCFRunLoopAllActivities = 0x0FFFFFFFU
};
複製代碼