什么是Runloop?
顾名思义,运行循环,在程序运行过程中做一些事情,Runloop也是一个对象。
应用范围:
1.定时器(Timer)、PerformSelector
2.GCD Async Main Queue。//GCD主线程(GCD的子线程是不需要Runloop的
3.事件响应、手势识别、界面刷新
4.网络请求
5.AutoreleasePool
如果没有Runloop程序运行完就会结束退出。
调用UIApplicationMain()函数会生成Runloop。
Runloop的基本作用:
1.保持程序的持续运行
2.处理APP中的各种时间(比如触摸时间、定时器事件等)
3.节省CPU资源,提高程序性能:该做事时做事,该休息时休息
4. …
iOS中有2套API来访问和使用Runloop:
- Foundation:NSRunLoop—OC的
- Core Foundation:CFRunLoopRef—C语言的
NSRunLoop 和 CFRunLoopRef都代表RunLoop对象
NSRunLoop是基于CFRunLoopRef的一层OC包装
CFRunLoopRef是开源的
RunLoop与线程:
1.每条线程都有唯一的一个与之对应的RunLoop对象
2.RunLoop保存在一个全局的Dictionary里,线程作为key,RunLoop作为value
3.线程刚创建时并没有RunLoop对象,RunLoop会在第一次获取它时创建
4.RunLoop会在线程结束时销毁
5.主线程的RunLoop已经自动获取(创建),子线程默认没有开启RunLoop
获取RunLoop对象:
Foundation框架下
- [NSRunLoop currentRunLoop]; //获得当前线程的RunLoop对象
- [NSRunLoop mainRunLoop]; //获得主线程的RunLoop对象
CFRunLoopModeRef:
1.CFRunLoopModeRef代表RunLoop的运行模式
2.一个RunLoop包含若干个Mode,每个Mode又包含若干个Source0/Source1/Timer/Observer
3.RunLoop启动时只能选择其中一个Mode,作为currentMode
4.如果需要切换Mode,只能退出当前Mode,再重新选择一个Mode进入
<1不同组的Source0/Source1/Timer/Observer能分隔开来,互不影响
5.如果Mode里没有任何Source0/Source1/Timer/Observer,RunLoop会立马退出
runloop有以下几种状态:**
/* Run Loop Observer Activities */
typedef CF_OPTIONS(CFOptionFlags,CFRunLoopActivity) {
kCFRunLoopEntry = (1UL << 0), // 即将进入Loop
kCFRunLoopBeforeTimers = (1UL << 1), // 即将处理Timer
kCFRunLoopBeforeSources = (1UL << 2),// 即将处理Source
kCFRunLoopBeforeWaiting = (1UL << 5),// 即将进入休眠
kCFRunLoopAfterWaiting = (1UL << 6), // 刚从休眠中唤醒
kCFRunLoopExit = (1UL << 7), // 即将退出Loop
kCFRunLoopAllActivities = 0x0FFFFFFFU
};