底层16:RunLoop
runloop:运行循环,在程序运行中循环做一些事情。
应用范畴:定时器(Timer)、PerformSelector、GCD Async Main Queue、事件响应、手势识别、界面刷新、网络请求、AutoreleasePool。
runloop的作用:
保持程序的持续运行;
处理App中的各种事件(eg:触摸事件,定时器事件);
节省CPU资源,提高程序性能(该做事的时候做事,该休息的时候休息)。
如果没有Runloop,下面代码执行完15行后,会即将退出程序。

如果有了runloop,程序不会马上退出,而是保持运行状态,如下,

UIApplicationMain方法中相当于创建了runloop,伪代码实现如下

RunLoop对象:
iOS中有2套API来访问和使用RunLoop:
Fundation:NSRunLoop(NSRunLoop是基于CFRunLoopRef的一层OC包装)
Core Fundation:CFRunLoopRef(c语言的,是开源的,https://opensource.apple.com/tarballs/CF)
NSRunLoop和CFRunLoopRef都代表着RunLoop对象。
RunLoop与线程
每条线程都有唯一的一个与之对应的RunLoop对象。
RunLoop保存在一个全局的Distionary里,线程作为key,RunLoop作为value。
线程刚创建时并没有RunLoop对象,RunLoop会在第一次获取它时创建。
RunLoop会在线程结束时销毁。
主线程的RunLoop已经自动获取(创建),子线程默认没有开启RunLoop。
获取RunLoop对象
Fundation:
[NSRunLoop currentRunLoop]; //获取当前线程的RunLoop对象
[NSRunLoop mainRunLoop]; //获取主线程的RunLoop对象
CFRunLoopRef:
CFRunLoopGetCurrent(); //获取当前线程的RunLoop对象
CFRunLoopGetMain(); //获取主线程的RunLoop对象
RunLoop相关的类

CFRunLoopModeRef:

常见的2种Mode:
kCFRunLoopDefaultMode(NSDefaultMode):APP的默认mode,选择主线程实在这个Mode下运行。
UITrackingRunLoopMode:界面跟踪Mode,用于ScrollView追踪触摸华东,保证界面滑动时不受其他Mode影响。

RunLoop运行逻辑


下面就是验证触摸事件是不是由Source0来处理的

CFRunLoopObserverRef

kCFRunLoopCommonModes默认包括kCFRunLoopDefaultMode和UITrackingRunLoopMode.
可以创建Obsever添加到RunLoop中去监听你想要的状态,如下:


获取用CFRunLoopObserverCreateWithHandler来创建,简单一些:

RunLoop休眠的实现原理
