1.定义
RunLoop,顾名思义就是运行循环。通过内部维护的一个循环事件对事件/消息进行管理。
2.本质及作用
runloop实际上就是一个高级do...while循环。一般的do...while循环会导致CPU进入忙等待状态,RunLoop则是“闲”等待,需要做事的时候忙起来,不需要的时候进入休眠。
基本作用:保持程序可以持续运行,可以处理APP的各种事件。RunLoop还节省cpu资源,帮助程序提高性能。
3.运行机制
在没有消息处理时休眠,有消息时又能唤醒,这样可以提高CPU资源使用效率。
4.运行范围
Timer,performSelector,GCD,界面刷新,网络请求,autoreleasepool,手势识别。
5.涉及的类
CFRunLoop:RunLoop对象;
CFRunLoopModel:五种RunLoop运行模式;
CFRunLoopSource:输入源/事件源,包括source0和source1;
CFRunLoopTimer:定时源,就是NStimer;
CFRunLoopObsever:观察者,用来监听RunLoop。
注:1.RunLoop是通过source来决定有没有任务做,除此外还可以用RunLoopObserver来监控RunLoop状态。
2.Source1:基于Match_Port,处理来自内核或其他进程事件,具备唤醒线程的能力。
Source0:基于Port的处理事件,也就是应用层事件,需要手动标记为待处理和手动唤醒RunLoop
6.RunLoop与线程
(1)每条线程都有唯一一个与之对应的RunLoop;
(2)线程刚创建的时候并没有RunLoop对象,只有在第一次获取的时候才会创建RunLoop;
(3)RunLoop保存在全局Dictionary中,线程为key,RunLoop为Value;
(4)RunLoop会在线程结束时销毁;
(5)主线程的RunLoop会自动创建,子线程默认是不开启RunLoop的,需要手动创建开启;
7.RunLoop休眠
休眠就是线程阻塞,但它和普通线程阻塞不一样。它是真的让线程休眠,不做任何事,cpu也不分配资源。一直等待线程被唤醒。要做到这样的休眠,只有内核API才能做到。所以:
休眠就是从用户态切换到内核态。把线程控制器交给内核态,这样的休眠则被挂起,不再占用CPU资源。
8.为什么主线程的RunLoop是自动开启的?
代码自动生成了autoreleasepool,这里就调用了RunLoop。APP启动时main函数就自动开启了主线程的runLoop。