深刻浅出 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
};
复制代码