RunLoop
iOS App 运行原理
App启动

01_动态链接 dyld
- 将程序依赖的动态链接库递归加载进内存
02_ImageLoader
image表示一个二进制文件(可执行文件或 so 文件),里面是被编译过的符号、代码等ImageLoader作用是将这些文件加载进内存,且每一个文件对应一个ImageLoader实例来负责加载- 在程序运行时它先将动态链接的
image加载 - 再从可执行文件
image递归加载所有符号
03_runtime

dyld开始将程序二进制文件初始化- 交由
ImageLoader读取image,其中包含了我们的类、方法等各种符号 - 由于
runtime向dyld绑定了回调,当image加载到内存后,dyld会通知runtime进行处理 runtime接手后调用map_images做解析和处理,接下来load_images中调用call_load_methods方法,遍历所有加载进来的Class,按继承层级依次调用Class的+load方法和其Category的+load方法
RunLoop
01_什么是RunLoop
- 使程序一直运行并接受用户输入
- 决定程序在何时应该处理那些
事件 - 消息队列
- 节省CPU时间
02_RunLoop 与 线程
线程和RunLoop之间是一一对应的(可嵌套),其关系是保存在一个全局的Dictionary里- 线程结束时销毁, 或手动退出
03_结构
|
|

Source
RunLoop 的数据源抽象类
RunLoop运行必须要在加入NSTimer或Source0、Sourc1、Observer输入后运行否则会直接退出
Source0: 处理App内部事件, App自行管理
- 包含了一个
函数指针,它并不能主动触发事件 - 调用
CFRunLoopSourceSignal(source),将这个 Source 标记为待处理 - 调用
CFRunLoopWakeUp(runloop)来唤醒 RunLoop,让其处理这个事件
Source1: 由RunLoop内核管理, MachPort驱动(进程间通讯)
- 包含了一个
mach_port和一个函数指针 - 被用于通过内核和其他线程相互发送消息
- 如解锁/摇晃等
Timer
- 包含了时长 和
函数指针
Observer
向外部报告 RunLoop 状态的变化
|
|
Observer 与 AutoreleasePool(UIKit)
Observer 在RunLoop两次Sleep间 Pop旧的并释放对象 Push新的
Mode
|
|
- 在同一时间必须且只能在一个
Mode下运行 - 切换
Mode必须退出RunLoop,重启 - 保证页面滑动流畅的关键
|
|
当创建一个
Timer并加到DefaultMode时,Timer会得到重复回调,但此时滑动一个TableView时,RunLoop会将mode切换为TrackingRunLoopMode,这时Timer就不会被回调,并且也不会影响到滑动操作。这两个Mode都已经被标记为Common
特殊Mode:
|
|
有时你需要一个
Timer,在两个Mode中都能得到回调,一种办法就是将这个Timer分别加入这两个Mode。还有一种方式,就是将Timer加入到顶层的RunLoop的commonModeItems中。commonModeItems被RunLoop自动更新到所有具有Common的Mode里去。

