Runtime
Runtime是Objective-c的运行时库,用于实现一些面向对象的特性,包括:
- 动态类型识别
- 动态方法解析
- 消息传递机制
实现原理涉及类结构、方法列表和消息传递机制
想要了解Runtime,需要了解下面一些东西。
类与对象结构:
类都是一个结构体,这个结构体包含了类的名称、父类的引用、成员变量列表、方法列表等信息。每个对象也是一个结构体,它包含了指向其类的指针以及实例变量的内存空间。
方法的存储与查找:
每个类都有一个方法列表,方法列表中包含了该类定义的所有方法。每个方法都有一个与之相关联的选择器(Selector),选择器是一个唯一的标识符,用于在运行时识别方法。在方法调用时,Runtime根据选择器找到对应的方法实现。
消息传递机制:
调用对象方法是,Runtime会通过对象结构中的方法列表找到对应的方法实现执行。
动态创建类:
Runtime通过objc_allocateClassPair函数创建类,然后通过class_addMethod方法添加方法,最后通过objc_registerClassPair注册类,使这个类在运行时可用。对象通过class_createInstance创建。
方法交换:
方法交换是通过交换两个方法在方法列表中的实现指针来实现的。
关联对象
关联对象是通过一张全局的哈希表来实现的。对象的地址作为 key,关联对象的信息作为 value 存储在这。
通过Runtime可以实现很多功能,如:
- 归档和解档
- KVO
- 容器类自动管理
- 方法转发和消息转发机制
RunLoop
RunLoop是一个事件处理循环,主要作用是监听并处理来自各种事件源的事件,使应用程序能够响应用户输入、定时任务等。
在程序启动时,主线线程会启动一个RunLoop。
RunLoop基本概念
- 输入源: 处理各种事件的基础,如键盘、鼠标事件。
- 定时器源: 运行在未来的某个时间执行任务,可以实现一些周期性操作。
- 自定义源: 可以在RunLoop中注册和处理自定义事件。
RunLoop Mode
RunLoop可以运行在不同模式下,每个模式都有一组特定输入源。
主要模式包括:
- Default Mode: 包含标准的输入源,是最常用的模式。
- Common Modes: 是一个集合,包含了一组常见的模式,包括Default Mode。它使得你可以在多个模式中处理事件。
RunLoop的状态
RunLoop有两种状态:
-
Active(活跃状态): 当RunLoop在处理事件时,处于活跃状态。
-
Inactive(非活跃状态): 当RunLoop没有处理事件时,处于非活跃状态。在非活跃状态下,RunLoop会休眠以节省CPU资源。
RunLoop的执行过程
RunLoop的执行过程通常是这样的:
- RunLoop启动(Run): 启动后进入活跃状态。
- 处理事件: 处理输入源、定时器源等事件。
- 等待: 如果没有事件要处理,RunLoop会进入休眠状态等待新的事件到来。
- 唤醒: 当有新事件到来时,RunLoop被唤醒,继续处理事件。
- RunLoop停止(Stop): 当应用程序退出或者手动停止RunLoop时,RunLoop停止。
注:开发过程一般不直接使用RunLoop,一般使用GCD处理异步任务,定时器处理定时任务,对RunLoop了解机制的原理就可以了。