RunLoop -- CFRunLoopRef
2020-04-11 本文已影响0人
踩坑小分队
RunLoop相关的类
Core Foundation中关于RunLoop的几个类
- CFRunLoopRef
- CFRunLoopModeRef
- CFRunLoopSourceRef
- CFRunLoopTimerRef
- CFRunLoopObserverRef
看一下的结构CFRunLoopRef
CFRunLoopRef是一个__CFRunLoop类型的结构体
typedef struct CF_BRIDGED_MUTABLE_TYPE(id) __CFRunLoop *
CFRunLoopRef;
当前只展示了重要的组成部分
struct __CFRunLoop {
CFRunLoopModeRef _currentMode;
CFMutableSetRef _modes;
};
看下其中的两个对象
CFRunLoopModeRef _currentMode;
CFMutableSetRef _modes;
一个__CFRunLoop中有一个 _currentMode,和多个_modes
CFRunLoopModeRef定义如下,是一个结构体
typedef struct __CFRunLoopMode *CFRunLoopModeRef;
struct __CFRunLoopMode {
CFMutableSetRef _sources0;
CFMutableSetRef _sources1;
CFMutableArrayRef _observers;
CFMutableArrayRef _timers;
};
总结来开RunLoop的结构是这个样子的
image.png
CFRunLoopModeRef
- CFRunLoopModeRef代表RunLoop的运行模式
- 一个RunLoop中含有多个Mode,每个Mode又包含很多个sources0/sources1/observers/timers
- RunLoop启动时,只能选择一个Mode作为currentMode
- 如果要切换Mode,只能是退出当前的Loop,重新选择一个Mode进入
优点:不同Mode组的sources0/sources1/observers/timers能相互分隔,相互没有影响 -
如果Mode中没有任何的sources0/sources1/observers/timers,那么RunLoop会退出
image.png
CFRunLoopModeRef种类
目前已知的Mode有5种
kCFRunLoopDefaultMode:App默认的Mode,通常主线程是运行在这个Mode下面的UITrackingRunLoopMode:界面跟踪Mode,用于scrollView追踪触摸滑动,保证界面滑动不受其他Mode的影响UIInitializationRunLoopMode:在刚启动App时进入的第一个Mode,通常用不到GSEventReceiveRunLoopMode:接受系统事件的内部Mode,通常用不到kCFRunLoopCommonModes:这是一个占位用的Mode,不算是真正的Mode
场景
可能系统刚启动的时候是运行在 UIInitializationRunLoopMode模式下,
然后切换到kCFRunLoopDefaultMode模式下,
当界面滑动的时候,又切换到UITrackingRunLoopMode,根据当前的场景不断的切换到不同的Mode下
RunLoop的运行逻辑
| Source0 | 1.触摸事件 2.performSelector:onThread |
|---|---|
| Source1 | 1.基于Port的线程间通信, 2.系统事件捕捉<比如点击时间,系统捕捉到点击事件,最后包装成Source0去处理> |
| Timers | 1.NSTimer 2.performSelector: withObject: afterDelay:<底层是NSTimer实现的> |
| Observers | 1.监听RunLoop的状态 2.UI界面的刷新(BeforeWaiting)<比如设置页面的背景颜色,不会马上生效,在RunLoop将要休眠之前会执行刷新> 3.自动释放池(BeforeWaiting) |
Source0
image.png
Timers
image.png