CFRunLoopModeRef
从上一篇中我们知道:
1.
CFRunLoopModeRef
代表RunLoop
的运行模式
2.一个RunLoop
包含若干个Mode
,每个Mode
又包含若干个Source0/Source1/Timer/Observer
3.RunLoop
启动时只能选择其中一个Mode
,作为currentMode
,如果需要切换Mode
,只能退出当前Loop
,再重新选择一个Mode
进入
4.不同组的Source0/Source1/Timer/Observer
能分隔开来,互不影响
5.如果Mode
里没有任何Source0/Source1/Timer/Observer
,RunLoop
会立马退出
在程序中我们常见的Model有两种:
1.
kCFRunLoopDefaultMode(NSDefaultRunLoopMode)
:App的默认Mode
,通常主线程是在这个Mode
下运行。
2.UITrackingRunLoopMode
:界面跟踪Mode
,用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他 Mode 影响
CFRunLoopObserverRef
CFRunLoopObserverRef
是观察者,能够监听RunLoop的状态改变。
Runloop的状态:
添加Observer
监听RunLoop
的所有状态的方法:
RunLoop的运行逻辑
关于model中对象的事件功能:
Source0
- 触摸事件处理
- performSelector:onThread:
Source1
- 基于Port的线程间通信
- 系统事件捕捉,然后再包装成Source0事件处理
Timers
- NSTimer定时器
- performSelector:withObject:afterDelay:(绑定线程执行或者方法延迟执行)
Observers
- 用于监听RunLoop的状态
- UI刷新(BeforeWaiting)
- Autorelease pool(BeforeWaiting)
runloop的处理流程:
- 通知Observers:进入Loop
- 通知Observers:即将处理Timers
- 通知Observers:即将处理Sources
- 处理Blocks
- 处理Source0(可能会再次处理Blocks)
- 如果存在Source1,就跳转到第8步
- 通知Observers:开始休眠(等待消息唤醒)
- 通知Observers:结束休眠(被某个消息唤醒)
当有这些任务中的某种过来:
01> 处理Timer
02> 处理GCD Async To Main Queue
03> 处理Source1 - 处理Blocks
- 根据前面的执行结果,决定如何操作
01>还有任务 -- 回到第02步
02> 没有任务了 --- 退出Loop - 通知Observers:退出Loop