RunLoop
1、概念
RunLoop是通过内部维护的事件循环,来对事件/消息进行管理的一个对象
2、事件循环:
没有消息需要处理时,休眠以避免资源占用
有消息需要处理时,立刻被唤醒
![](https://i-blog.csdnimg.cn/blog_migrate/adc45df2f5c964d4816cd3126a6a6841.png)
事件循环
![](https://i-blog.csdnimg.cn/blog_migrate/7ec3deb637f3018f8f42c7c8989c9218.png)
RunLoop
3、数据结构
NSRunLoop是不开源的,CDRunLoop是开源的
![](https://i-blog.csdnimg.cn/blog_migrate/8863847350e304184b9eac27964d295c.png)
数据结构
- CFRunLoop
![](https://i-blog.csdnimg.cn/blog_migrate/1325601878669b70f7c15a29eb53252e.png)
CFRunLoop
- CFRunLoopMode
![](https://i-blog.csdnimg.cn/blog_migrate/58b838e6e4654591129b19c77e970f8a.png)
CFRunLoopMode
- CFRunLoopSource
![](https://i-blog.csdnimg.cn/blog_migrate/14850b8e44d835622a3cb3a711c36574.png)
CFRunLoopSource
- CFRunLoopTimer
![](https://i-blog.csdnimg.cn/blog_migrate/8bf39777a4bc2930f061972f42550c55.png)
CFRunLoopTimer
-
CFRunLoopObserver
可以观测6个时间点
kCFRunLoopEntry 进入RunLoop
kCFRunLoopBeforeTimers 即将处理Timers一些事件
kCFRunLoopBeforeSources 即将处理Sources一些事件
kCFRunLoopBeforeWaiting 即将进入休眠 即将从用户态->内核态切换
kCFRunLoopAfterWaiting 内核态->用户态切换后的不久
kCFRunLoopExit RunLoop退出
![](https://i-blog.csdnimg.cn/blog_migrate/27f43934b4a7baac3c184841371387df.png)
数据关系
4、RunLoop的Mode
- 如果运行在一个Mode上,只能接受当前Mode的事件,其他Mode不会运行
![](https://i-blog.csdnimg.cn/blog_migrate/6d63ccf8c425a55250d4aa527f454f29.png)
多Mode
- CommonMode的特殊性
![](https://i-blog.csdnimg.cn/blog_migrate/bae28cf9d4c6faf68b7ca24bde9f44ba.png)
CommonMode
5、事件循环的实现机制
- 启动会调用CDRunLoopRun( )方法
![](https://i-blog.csdnimg.cn/blog_migrate/b7c698794d0ec2729c487ed699eb6ffd.png)
实现机制
🌰:main函数调用后会调用UIApplicationMain方法,方法内部会启动主线程的RunLoop,经过一系列处理,主线程的RunLoop处于休眠状态,此时点击一下屏幕会产生一个mach-port,会转换成一个Source1,唤醒主线程,然后运行处理,当程序被杀死就会退出RunLoop,线程被杀死。
6、RunLoop的核心
![](https://i-blog.csdnimg.cn/blog_migrate/2c908f71a5d0f88a33731cb8e8e17673.png)
RunLoop的核心
7、RunLoop与NSTimer
![](https://i-blog.csdnimg.cn/blog_migrate/e94e24b4ec1c54f254a6c8df317789af.png)
RunLoop与NSTimer
- void CFRunLoopAddTimer(runLoop, timer, commonMode)
![](https://i-blog.csdnimg.cn/blog_migrate/d48f68f5f06089afc266ec53fe5bddc1.png)
CFRunLoopAddTimer
- void __CFRunLoopAddItemToCommonModes(const void *value, void *ctx)
![](https://i-blog.csdnimg.cn/blog_migrate/998d49b8332c8e1a94585c7c6007c276.png)
CFRunLoopAddItemToCommonModes
8、RunLoop与多线程
![](https://i-blog.csdnimg.cn/blog_migrate/3dfa0ae2b7fbbc2eae23d439c95510b1.png)
RunLoop与多线程
- 常驻线程
获取当前线程的RunLoop,如果当前线程没有RunLoop会自动创建一个
[NSRunLoop currentRunLoop];
![](https://i-blog.csdnimg.cn/blog_migrate/d236250427a935f20a5a2ea0524b4dc6.png)
image-20211006121545588
- 创建一个常驻线程
![](https://i-blog.csdnimg.cn/blog_migrate/35346cf3e766621da57f2d69ca035174.png)
常驻线程