返回
奔赴主线程之约,揭开 RunLoop 的源码奥秘
IOS
2023-11-23 05:45:55
从源码来理解 RunLoop 原理
前言
当 App 启动时,系统会为其创建并启动一个称为主线程或 UI 线程的线程。主线程用于处理用户界面更新、事件响应和其他与用户交互相关的任务。为了管理主线程上的任务和事件,系统创建了一个称为 RunLoop 的机制。
RunLoop 的使命
RunLoop 负责以下重要任务:
- 接收和处理来自各种来源的事件,如触摸事件、传感器数据和计时器回调。
- 将事件分派到适当的对象进行处理。
- 执行与事件无关的计划任务,例如动画和网络请求。
源码探秘
要理解 RunLoop 的原理,让我们深入到 iOS 框架的源码中。RunLoop 的核心逻辑位于 CoreFoundation/RunLoop.h
头文件中:
typedef struct __CFRunLoop* CFRunLoopRef;
struct __CFRunLoop {
...
CFMutableSetRef commonModes;
CFRunLoopTimerRef currentTimer;
CFRunLoopSourceRef currentSource;
...
};
结构体概览
CFRunLoop
结构体代表一个 RunLoop 实例。它包含以下关键成员:
commonModes
:一个存储公共模式的集合,这些模式允许跨多个 RunLoop 实例共享源和定时器。currentTimer
:当前正在执行的定时器。currentSource
:当前正在执行的事件源。
运作原理
RunLoop 遵循一个消息循环的模式。这个循环不断重复以下步骤:
- 获取事件: RunLoop 从其事件源队列中获取事件。
- 分派事件: 将事件分派到适当的对象进行处理。
- 执行任务: 执行来自计时器或其他来源的计划任务。
- 休眠: 如果队列中没有更多事件或任务,RunLoop 会进入休眠状态,直到有新的事件或任务出现。
源码中的休眠
RunLoop 的休眠机制通过 CFRunLoopRunInMode
函数实现:
Boolean CFRunLoopRunInMode(CFStringRef mode, CFTimeInterval seconds, Boolean returnAfterSourceHandled);
mode
:要运行的模式(例如 kCFRunLoopDefaultMode)。seconds
:RunLoop 应在休眠之前等待事件或任务的秒数。returnAfterSourceHandled
:指示 RunLoop 是否应在处理完事件源后立即返回。
结语
RunLoop 是 iOS App 架构中的一个基本组件,负责管理主线程上的事件和任务处理。通过分析其源码,我们揭示了其内部运作机制,了解到它如何通过消息循环模式协调用户交互、动画和其他后台任务。掌握 RunLoop 的原理对于优化 App 性能和响应能力至关重要。