运行循环,在程序运行过程中循环做一些事情,在没有操作的时候就停下来休息。充分节省CPU资源,提高程序性能。
一、 RunLoop基本作用
保持程序持续运行,程序一启动就会开一个主线程,主线程一开起来就会跑一个主线程对应的RunLoop,RunLoop保证主线程不会被销毁,也就保证了程序的持续运行。
处理App中的各种事件。(比如:触摸事件,定时器事件,Selector事件等)
节省CPU资源,提高程序性能,程序运行起来时,没有操作的时候,RunLoop就告诉CUP,现在没有事情做,我要去休息,这时CUP就会将其资源释放出来去做其他的事情,当有事情做的时候RunLoop就会立马起来去做事情。
二、RunLoop在哪里开启,Runloop和线程的关系
1、Runloop在第一次获取时创建,在线程结束时销毁。
UIApplicationMain函数内启动了Runloop,程序不会马上退出,而是保持运行状态。RunLoop在程序的入口main函数中开启。
2、Runloop和线程一一对应,主线程的Runloop已经创建,子线程的必须手动创建。Runloop是线程的基础架构部分。
3、Runloop中的自动释放池什么时候释放?
1.启动Runloop的时候,自动释放池第一次创建。
2.Runloop退出的时候,自动释放池最后一次销毁。
3.当Runloop即将睡眠时会销毁之前的释放池,重新创建一个新的释放池。
三、RunLoop 的实现机制
对于 RunLoop 而言最核心的事情就是保证线程在没有消息的时候休眠,在有消息时唤醒,以提高程序性能。
RunLoop 这个机制是依靠系统内核来完成的(苹果操作系统核心组件 Darwin 中的 Mach)。 RunLoop 通过 mach_msg()函数接收、发送消息。它的本质是调用函数 mach_msg_trap(),相当于是 一个系统调用,会触发内核状态切换。
在用户态调用 mach_msg_trap()时会切换到内核态;内核态中内核实现的 mach_msg()函数会完成实际的工作。 即基于 port 的 source1,监听端口,端口有消息就会触发回调;而 source0,要手动标记为待处理和手动唤醒 RunLoop
大致逻辑为:
1、通知观察者 RunLoop 即将启动。
2、通知观察者即将要处理 Timer 事件。
3、通知观察者即将要处理 source0 事件。
4、处理 source0 事件。
5、如果基于端口的源(Source1)准备好并处于等待状态,进入步骤 9。
6、通知观察者线程即将进入休眠状态。
7、将线程置于休眠状态,由用户态切换到内核态,直到下面的任一事件发生才唤醒线程。
一个基于 port 的 Source1 的事件(图里应该是 source0)。
一个 Timer 到时间了。
RunLoop 自身的超时时间到了。
被其他调用者手动唤醒。
8、通知观察者线程将被唤醒。
9、处理唤醒时收到的事件。
如果用户定义的定时器启动,处理定时器事件并重启 RunLoop。进入步骤 2。
如果输入源启动,传递相应的消息。
如果 RunLoop 被显示唤醒而且时间还没超时,重启 RunLoop。进入步骤 2
10、通知观察者 RunLoop 结束。
四、RunLoop 的 Mode
关于 Mode 首先要知道一个 RunLoop 对象中可能包含多个 Mode,且每次调用 RunLoop 的主函数时, 只能指定其中一个 Mode(CurrentMode)。切换 Mode,需要重新指定一个 Mode 。主要是为了分隔开不 同的 Source、Timer、Observer,让它们之间互不影响。
当 RunLoop 运行在 Mode1 上时,是无法接受处理 Mode2 或 Mode3 上的 Source、Timer、Observer 事 件的
CFRunLoopMode:总共是有五种
1.kCFRunLoopDefaultMode:默认模式,主线程是在这个运行模式下运行
2.UITrackingRunLoopMode:跟踪用户交互事件(用于 ScrollView 追踪触摸滑动,保证界面滑 动时不受其他 Mode 影响)
3.UIInitializationRunLoopMode:在刚启动 App 时第进入的第一个 Mode,启动完成后就不 再使用
4.GSEventReceiveRunLoopMode:接受系统内部事件,通常用不到 5.kCFRunLoopCommonModes:伪模式,不是一种真正的运行模式,是同步 Source/Timer/Observer 到多个 Mode 中的一种解决方案
参考链接:
[Runloop 深入浅出,综合解答]
(https://blog.csdn.net/hherima/article/details/51746125)
https://www.jianshu.com/p/de752066d0ad