RunLoop是开源的:RunLoop源码下载地址
RunLoop是事件接收和分发机制的一个实现,是消息机制的处理模式。
什么是RunLoop?
- 内部就是do-while循环,这个循环内部不断地处理各种任务(如:Sources、Observer、Timer)
- 一个线程对应一个RunLoop,主线程的RunLoop默认已经启动,子线程的RunLoop需要手动启动(调用run方法)
- RunLoop只能选择一个mode启动,如果当前mode中没有任何Sources(Source0、Source1)、Timer,那么直接退出RunLoop
RunLoop与线程:
RunLoop主要目的是保证程序执行的线程不会被系统终止
每条线程都有唯一的一个与之对应的RunLoop对象
主线程的RunLoop已经自动创建好了,子线程的RunLoop需要主动创建
RunLoop在第一次获取时创建,在线程结束时销毁
Core Foundation中关于RunLoop的5个类:
CFRunLoopRef --- 包含了若干个CFRunLoopModeRef对象
CFRunLoopModeRef --- RunLoop的对象(若干个),是一个集合,包括监听:事件源、定时器,以及需要通知Observers
CFRunLoopSourceRef --- CFRunLoopModeRef对象中的Set类型元素(若干个)
CFRunLoopTimerRef --- CFRunLoopModeRef对象中的Array类型元素(若干个)
CFRunLoopObserverRef --- CFRunLoopModeRef对象中的Array类型元素(若干个)
其中CFRunLoopSourceRef的分类
-
理论分类
-
实践分类(按照
函数调用栈
分类)- Source0(非基于Port的)
- Source1(基于Port的 --- 通过内核和其它线程通信,接收、分发系统事件)
Source1接收到事件后,会分发给Source0去处理
Xcode中获取RunLoop:
Foundation:
[NSRunLoop currentRunLoop]; // 获得当前线程的RunLoop对象
[NSRunLoop mainRunLoop]; // 获得主线程的RunLoop对象
Core Foundation:
CFRunLoopGetCurrent(); // 获得当前线程的RunLoop对象
CFRunLoopGetMain(); // 获得主线程的RunLoop对象
CFRunLoopModeRef 系统默认注册了5个Mode:
kCFRunLoopDefaultMode:App的默认Mode,通常主线程是在这个Mode下运行
UITrackingRunLoopMode:界面跟踪 Mode,用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他 Mode 影响
UIInitializationRunLoopMode: 在刚启动 App 时第进入的第一个 Mode,启动完成后就不再使用 ---- <用不上>
GSEventReceiveRunLoopMode: 接受系统事件的内部 Mode,通常用不到 ---- <用不上>
kCFRunLoopCommonModes: 这是一个占位用的Mode,不是一种真正的Mode