RunLoop
我们从字面意思可以看出:运行循环,跑圈。
基本作用
- 保持程序的持续运行
- 处理App中的各种事件,例如触摸事件,定时器事件,Seletor事件
- 节省CPU资源,提高程序性能:该做事的时候做事,该休息的时候休息
由于main函数中
UIApplicationMain
函数内部启动了一个RunLoop
,永远不会返回,所以程序不会马上退出,保持持续运行状态。
- 默认启动的
RunLoop
跟主线程是相关联的
RunLoop对象
Foundation -> NSRunLoop
Core Foundation -> CFRunLoopRef
NSRunLoop
和CFRunLoopRef
都代表着Runloop对象
NSRunLoop
是基于CFRunLoopRef
的一层OC包装,所以要了解RunLoop内部结构,需要多研究CFRunLoopRef
层面的API(Core Foundation
层面)
相关资料
官方:https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html
CFRunLoopRef
开源:http://opensource.apple.com/source/CF/CF-1151.16
RunLoop与线程
- 每条线程都有唯一的一个与之对应的RunLoop对象
- 主线程的RunLoop已经自动创建好了,子线程的RunLoop需要主动创建并开启
- RunLoop在第一次获取时创建,在线程结束时销毁
获取RunLoop对象
Foundation
[NSRunLoop currentRunLoop]
获取当前线程的RunLoop对象[NSRunLoop mainRunLoop]
获取主线程的RunLoop对象
Core Foundation
CFRunLoopGetCurrent()
获取当前线程的RunLoop对象CFRunLoopGetMain()
获取主线程的RunLoop对象
子线程获取RunLoop
currentRunLoop
该方法本身就是懒加载,如果第一次调用时候会创建当前线程对应的RunLoop,并保存,以后调用直接获取
NSRunLoop *threadRunLoop = [NSRunLoop currentRunLoop];
[threadRunLoop run];
相关类
Core Foundation
CFRunLoopRef
CFRunLoopModeRef
CFRunLoopSourceRef
CFRunLoopTimerRef
CFRunLoopObserverRef
CFRunLoopModeRef
1.
CFRunLoopModeRef
代表RunLoo
的运行模式
2.一个RunLoop
包含若干个Mode
,每个Mode
又包含若干个Source/Timer/Observer
3.每次RunLoop
启动时,只能指定其中一个Mode
,这个Mode
被称作CurrentMode
4.如果需要切换Mode
,只能退出RunLoop
,在重新指定一个Mode
进入
5.这样做主要是为了分隔开不同组的Source/Timer/Observer
,让其互不影响
系统默认注册的5个Mode
1.kCFRunLoopDefaultMode
:App默认的Mode,通常主线程是在这个Mode下运行
2.UITrackingRunLoopMode
:界面跟踪Mode,用于ScrollView追踪触摸滑动,保证界面滑动时不受其他Mode影响
3.UIInitializationRunLoopMode
:在刚启动App时,第一个进入的Mode,启动完成后就不在使用
4.GSEventReceiveRunLoopMode
:接手系统事件的内部Mode,通常用不到
5.kCFRunLoopCommonModes
:这是一个占位的Mode,不是一种真正的Mode
CFRunLoopObserverRef
CFRunLoopObserverRef
是观察者,能够监听RunLoop的状态改变
可以监听的时间点有以下几个:
kCFRunLoopEntry
即将进入LoopkCFRunLoopBeforeTimers
即将处理TimerkCFRunLoopBeforeSource
即将处理SourcekCFRunLoopBeforeWaiting
即将进入休眠kCFRunLoopAfterWaiting
刚从休眠中唤醒kCFRunLoopExit
即将退出Loop