RunLoop
RunLoop内容如下
- 概念
- 数据结构
- 事件循环
- RunLoop与NSTimer
- RunLoop与多线程
1.概念
什么是RunLoop ?
RunLoop是通过内部维护的事件循环来对事件/消息进行管理的一个对象
事件循环:
- 没有消息需要处理时,休眠以避免资源占用;(用户态-- (通过系统调用)--进入内核态),
我们没有消息处理时,我们的进程/线程进入休眠状态,休眠状态的过度,当前线程的控制权交给内核态.
- 有消息需要处理时,立刻被唤醒.(内核态到用户态的状态切换)
- 用户态:我们的应用程序一般都是应用在用户态
- 内核态:使用操作系统,系统内核,对计算机资源调度的操作,合理安排资源调度(关机,中断)
2.数据结构
NSRunLoop是CFRunLoop的封装
Foundation ---CFFoundation
- CFRunLoop
- CFRunLoopMode
- Source/Timer/Observer
- CFRunLoop
- pthread RunLoop和线程一一对应的关系
- currentMode CFRunLoopMode
- modes NSMutableSet
- commonModes NSMutableSet
- commonModeItems
- CFRunLoopMode
name - NSDefaultRunLoopMode
sources0,sources1 属于集合类型,MutableSet
observes,timers 属于数组类型,MutableArray
- CFRunLoopSource
source0
需要手动唤醒线程
source1
具备唤醒线程的能力
source0与source1的区别
- CFRunLoopTimer
- 基于事件的定时器
- 与NSTimer 免费桥接转换的
- CFRunLoopObserver
时间点:
- kCFRunLoopEntry
- kCFRunLoopBeforeTimers
- kCFRunLoopBeforeSources
- kCFRunLoopBeforeWaiting
- kCFRunLoopAfterWaiting
- kCFRunLoopExit
- RunLoop与线程一一对应的关系
- RunLoop与Model,一对多的关系
- RunLoop与(Source,Timer,Observer),一对多的关系
- RunLoop的Mode
思考 为什么RunLoop有多个mode?
为什么我们滑动tableview,广告栏不会滚动了,这是为什么?
- 如果timer想要加入到两个mode里面,我们该怎么做?
- timer想在mode1上做响应的处理,在mode2上也做响应的处理
- timer怎样同时加入两个mode
- NSRunLoopCommonModes
- NSRunLoopCommonModes
- CommonMode不是实际存在的一种Mode
- 是同步Source/Timer/Observer到多个Mode中的一种技术方案
3.事件循环的实现机制
void CFRunLoopRun()
当一个处于休眠的runloop,我们可以通过哪些方式唤醒它?
Source1
Timer事件
外部手动唤醒
- 在RunLoop启动之后,会发送一个通知,告诉观察者RunLoop即将启动
- RunLooop将要处理Timer/Source0事件
- 正式进入Source0事件处理
- 如果有Source1要处理,通过goto语句,代码逻辑的跳转,处理唤醒时收到的消息
- 如果没有Source1要处理的话,线程将要休眠(用户态到内核态的切换)
- 休眠,等待唤醒(Source1,Timer事件,外部手动唤醒)
- 线程刚被唤醒(内核态到用户态切换)
App通过点击一个图标到启动,运行,退出,这个过程当中系统都发生了什么?
- 我们调用main函数之后,会调用UIApplicationMain函数,在函数内存,会启
动主线程的runloop,经过一系列的处理,runloop进行一些事件处理.
- 当程序杀死的时候,发送一个通知,即将推出Runloop.当推出runloop的时候,线程就销毁掉了.
4.RunLoop与NSTimer
思考 滑动TableView的时候我们的定时器还会生效吗?
- kCFRunLoopDefaultModel--mode发生切换,UITrackingRunLoopMode(不会在生效)
- 可以添加到CommonMode上
5.RunLoop与多线程
- 线程和RunLoop一一对应的
- 自己创建的线程默认是没有RunLoop的
怎样实现一个常驻线程?
- 为当前线程开启一个RunLoop
- 向该RunLoop中添加一个Port/Source等维持RunLoop的事件循环.
- 启动该RunLoop
6.面试题
什么是RunLoop,它是怎样做到有事做事,没事休息的?
RunLoop与线程是怎样的关系?
如何实现一个常驻线程?
怎样保证子线程数据回来更新UI的时候不打断用户滑动操作?
QQ交流群: 796142709