iOS进阶五-RunLoop
2019-05-22 17:56 iCoderHong 阅读(362) 评论(0) 编辑 收藏 举报简介
RunLoop 运行循环、跑圈
RunLoop的作用主要体现在三方面:
1.保持程序持续运行
2.处理App中的各种事件(比如触摸事件、定时器事件、Selector事件)
3.节省CPU资源,提高程序性能:该做事的时候做事,该休息的时候休息
在iOS中访问RunLoop🈶2套API
- Foundation:NSRunLoop
- Core Foundation: CFRunLoopRef
NSRunLoop是基于CFRunLoopRef的一层OC包装,因此我们需要研究CFRunLoopRef层面的API(Core Foundation层面)
RunLoop与线程
- RunLoop保存在全局的Dictionary里,线程作为key,RunLoop作为Value
- 每条线程都有唯一的一个与之对应的RunLoop 线程创建时并没有RunLoop对象,RunLoop会在第一次获取它时创建
-
主线程的RunLoop是UIApplicationMain函数获取创建的,子线程默认没有开启RunLoop
- RunLoop会在线程结束时销毁
RunLoop相关类数据结构
CFRunLoopMode
一个RunLoop包含若干个Mode(RunLoop的运行模式) RunLoop启动时只能选择一个Mode作为currentMode
每个Mode又包含若干个Source0/Source1/Timers/Observers
RunLoop一旦启动,就会监听循环处理当前currentMode下的Source0/Source1/Timers/Observer
常见的2中Mode
- kCFRunLoopDefaultMode/NSDefaultRunLoopMode:App的默认Model 通常主线程在这个Mode下运行
- UITrackingRunLoopModel:界面跟踪Mode,用于ScrollView追踪触摸滑动,保证页面滑动时不受其它Mode影响
事件类型 |
事件举例 |
Source0 |
基于Port的线程间通信(NSPortMessage NSPort) performSelector:onThread:是通过_Source0来处理 |
Source1 |
基于Port的线程间通信(NSPortMessage NSPort) 系统事件的捕捉 |
Timers |
NSTimer performSelector:withObject:afterDelay: |
Observers |
用于监听RunLoop的状态 UI刷新(BerforeWaiting) Autorelease pool(BerforeWaiting) |
CFRunLoopObserversRef
CFRunLoop源码中定义RunLoop状态
给RunLoop添加Observers 监听RunLoop状态
RunLoop切换Mode需要退出当前Loop,再重新选择一个Model进入,对应的两个状态kCFRunLoopEntry和KCFRunLoopExit,可以通过滑动UIScrollView切换模式验证
RunLoop的运行逻辑
RunLoop 循环 具体要做的业务如下
RunLoop的运行逻辑流程图
RunLoop休眠的实现原理
RunLoop在实际开发中的应用
- 控制线程声明周期(线程保活)
- 解决NSTimer在滑动时停止工作问题
- 监控应用程序卡顿
- 性能优化