文章目录
实际上是一个对象,这个对象提供一个入口函数,执行这个入口函数后,程序会进入一个do…while循环,不断的处理事件,节省cpu资源,提高利用率.
通过内部维护的事件循环来对事件/消息进行管理的一个对象
- 没有消息需要处理时,休眠以避免资源占用
- 有消息需要处理时,立刻被唤醒
1. 基本作用
- 保持程序的持续运行
- 处理App中的各种事件(触摸事件,定时器事件,performSelect)
- 节省CPU资源,提高程序性能(该做事的时候做事,该休息的时候休息)
2. RunLoop对象
Foundation : NSRunLoop
Core Foundation : CFRunLoopRef
NSRunLoop 和 CFRunLoopRef都代表着RunLoop对象
NSRunLoop是基于CFRunLoopRef的一层OC包装
3. RunLoop与线程
- 每条线程都有一个唯一的一个与之对应的RunLoop对象
- RunLoop保存在一个全局的Dictionary里,线程为key, RunLoop为value
- 线程刚刚创建的时候,并没有RunLoo对象,RunLoop会在第一次获取它的时候创建
- RunLoop会在线程结束时销毁
- 主线程的RunLoop已经自动获取(创建),子线程默认没有开启RunLoop
1. 获取runloop对象
// Foundation
[NSRunLoop currentRunLoop];//获取当前线程的runloop
[NSRunLoop mainRunLoop];//获取主线程的runloop
// Core Foundation
CFRunLoopGetCurrent();//获取当前线程的runloop
CFRunLoopGetMain();//获取主线程的runloop
2. RunLoop相关的类
- _pthread : 一个runloop对应一个_pthread线程.
- _modes : 一个runloop包含多个mode(默认模式,UI追踪模式,GSEventReceiveRunLoopMode)
- 每个mode中又包含了若干个source/timer/observer
- source/timer/observer 又叫做modeItem,不同mode下的modeitem互不影响
- _currentMode : 当前正在运行的模式,runloop只能运行在一种模式下. 如果要切换模式,退出当前正在运行的模式,然后重新定制的mode执行
- _commonModesItems : 加入NSRunLoopCommonModes模式下的对象会被放入这个集合中
- _commonModes : 里面包含了默认模式 和UI追踪模式
- 如果mode中没有任何source0/source1/observer , runloop会立马退出
3. CFRunLoopObserverRef
- 添加Observer监听RunLoop的所有状态
// CFRunLoopObserverCreate(<#CFAllocatorRef allocator#>, <#CFOptionFlags activities#>, <#Boolean repeats#>, <#CFIndex order#>, <#CFRunLoopObserverCallBack callout#>, <#CFRunLoopObserverContext *context#>)
//CFRunLoopObserverContext 是一个结构体
//创建observer
CFRunLoopObserverRef observer = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopAllActivities, YES, 0, observerCallBack, NULL);
//添加observer
CFRunLoopAddObserver(CFRunLoopGetMain(), observer, kCFRunLoopDefaultMode);
//通过create copy得到的, 最后都需要释放
CFRelease(observer);
4. runloop的运行逻辑
- source0
触摸事件处理 , P而formSelector:onThread:- source1
一般处理系统的事件- Timer
NSTimer , performSelector:withObject:afterDelay:- Observers
用于监听runloop的状态
UI刷新(beforewaiting)
autorelease pool (beforewaiting)
5.runloop在实际开发中的应用
- 控制线程生命周期
- 解决NSTimer在滑动时停止工作的问题
- 监控应用卡顿
- 性能优化
定时器
要想定时器在UI滑动的时候也不会停止工作
[[NSRunLoop currentRunLoop] addTimer:time forMode:NSRunLoopCommonModes];
CFRunLoopAddTimer(<#CFRunLoopRef rl#>, <#CFRunLoopTimerRef timer#>, <#CFRunLoopMode mode#>)
把定时器加入了 _commonModeItems , (加入了默认模式,和UI追踪模式)
__CFRunLoopAddItemToCommonModes : 把timer添加到每一个mode中
runloop 流程