什么是RunLoop
每条线程都有唯一一个与之对应的RunLoop对象
RunLoop保存在一个全局的Dictionary里,线程作为key,RunLoop作为Value
线程刚创建时并没有RunLoop对象,RunLoop会在第一次获取他时创建
RunLoop会在线程结束时销毁
创建的源码:
CFRunLoopGetMain获取主线程RunLoop
CFRunLoopGetCurrent获取当前线程RunLoop
CFRunLoop结构体:全局搜索struct __CFRunLoop {
CFRunLoopMode结构体:全局搜索struct __CFRunLoopMode {
可以看到一个CFRunLoop结构体里有很多CFRunLoopMode,每一个mode里有很多sources0,sources1,observers,timers
Sources0:触摸事件,PerformSelector
Sources1:基于Port的线程间通信
Timers:定时器
Observers:监听器,用来监听Runloop的状态
RunLoop的运行逻辑:
1.通知Observer,进入Loop
2.通知Observer,即将处理Timers
3.通知Observer,即将处理Sources
4.处理BLocks
5.处理Sources0(可能会再次处理Blocks)
6.如果存在Sources1,跳转到第8步
7.开始休眠
8.被某个消息唤醒
处理Timer
处理GCD Async To Main Queue
处理Sources1
9.处理Blocks
10.根据前面的执行结果,决定回到第二步还是退出Loop
11.通知Observer,退出Loop
RunLoop的应用:
1.线程保活
2.解决NSTimer在滑动时停止工作的问题
3.监控应用卡顿
4.让APP崩溃时起死回生
5.性能优化