1、什么是RunLoop
顾名思义,就是运行循环,它会在程序运行过程中循环做一些事情。
应用范畴:
定时器(Timer)、PerformSelector、GCD Async Main Queue、事件响应、手势识别、界面刷新、网络请求、AutoreleasePool。
2、RunLoop做了什么
保证程序并不会马上退出,而是保持运行状态,RunLoop的基本作用:
保持程序的持续运行
处理App中的各种事件(比如触摸事件、定时器事件等)
节省CPU资源,提高程序性能:该做事时做事,该休息时休息
……
iOS项目mian函数内部的UIApplicationMain方法会创建一个RunLoop并开启,伪代码如下:
3、获取RunLoop
iOS中有两套RunLoopAPI,Foundation里的NSRunLoop和Core Foundation里的CFRunLoopRef:
// 获取当前runLoop
NSRunLoop * runLoop1 = [NSRunLoop currentRunLoop];
// 获取主runLoop
NSRunLoop * runLoop2 = [NSRunLoop mainRunLoop];
// 获取当前runLoop
CFRunLoopRef runLoop3 = CFRunLoopGetCurrent();
// 获取主runLoop
CFRunLoopRef runLoop4 = CFRunLoopGetMain();
NSRunLoop是基于CFRunLoopRef的一层OC包装,CFRunLoopRef 是开源的。
NSLog(@"%p %p",[NSRunLoop currentRunLoop], CFRunLoopGetCurrent());
分别打印NSRunLoop和CFRunLoopRef,地址并不相同,证明了NSRunLoop并不是等价于CFRunLoopRef,而是对CFRunLoopRef进行了包装。
4、RunLoop和线程的关系
每条线程都有唯一的一个与之对应的RunLoop对象。
RunLoop保存在一个全局的Dictionary里,线程作为key,RunLoop作为value。
线程刚创建时并没有RunLoop对象,RunLoop会在第一次获取它的时候创建。
RunLoop会在线程结束时销毁。
主线程的RunLoop已经自动获取(创建),子线程默认没有开启RunLoop。