1.RunLoop对象
iOS中有两套API来访问和使用RunLoop
Core Foundation框架:CFRunLoopRef,是开源的
Foundation框架:NSRunLoop,基于CFRunLoopRef的一层OC包装
2.获取RunLoop对象
[NSRunLoop currentRunLoop]; // 获得当前线程的RunLoop对象
CFRunLoopGetCurrent(); // 获得当前线程的RunLoop对象
[NSRunLoop mainRunLoop]; // 获得主线程的RunLoop对象
CFRunLoopGetMain(); // 获得主线程的RunLoop对象
3.RunLoop相关的类
CFRunLoopRef 、CFRunLoopModeRef、CFRunLoopSourceRef 、CFRunLoopTimerRef 、CFRunLoopObserverRef
- CFRunLoopModeRef
1>CFRunLoopModeRef代表RunLoop的运行模式
2> 一个RunLoop包含若干个Mode,每个Mode又包含若干个Source0/Source1/Timer/Observer
3>RunLoop启动时只能选择其中一个Mode,作为currentMode
4>如果需要切换Mode,只能退出当前Loop,再重新选择一个Mode进入, 不同组的Source0/Source1/Timer/Observer能分隔开 来,互不影响
5>如果Mode里没有任何Source0/Source1/Timer/Observer,RunLoop会立马退出
- CFRunLoopModeRef
常见的两种Mode:
1>kCFRunLoopDefaultMode(NSDefaultRunLoopMode):App的默认Mode,通常主线程是在这个Mode下运行
2>UITrackingRunLoopMode:界面跟踪 Mode,用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他 Mode 影响
- CFRunLoopObserverRef
添加Observer监听RunLoop的所有状态
4.RunLoop运行逻辑
- Source0
1>触摸事件处理
2>performSelector:onThread:
- Source1
1>基于Port的线程间通信
2>系统事件捕捉
- Timers
1>NSTimer
2>performSelector:withObject:afterDelay:
- Observers
1.用于监听RunLoop的状态,比如UI刷新和AutoreleasePool释放有可能在BeforeWaiting的时候。
- RunLoop整个运行逻辑
01、通知Observers:进入Loop
02、通知Observers:即将处理Timers
03、通知Observers:即将处理Sources
04、处理Blocks 05、处理Source0(可能会再次处理Blocks)
06、如果存在Source1,就跳转到第8步
07、通知Observers:开始休眠(等待消息唤醒)
08、通知Observers:结束休眠(被某个消息唤醒)
01> 处理Timer
02> 处理GCD Async To Main Queue
03> 处理Source1
09、处理Blocks
10、根据前面的执行结果,决定如何操作
01> 回到第02步
02> 退出Loop
11、通知Observers:退出Loop
RunLoop休眠的实现原理:
是由用户态切换到内核态实现休眠,用户态只能处理应用层,内核层面的api可以达到线程休眠,while(1)是用户态下的线程阻塞,但是线程没有休眠
来源:CSDN
作者:史蒂芬-周
链接:https://blog.csdn.net/HuberCui/article/details/103609771