
Runtime简称运行时。OC就是运行时机制,也就是在运行时候的一些机制,其中最主要的是消息机制;
对于C语言,函数的调用在编译的时候会决定调用哪个函数;
对于OC的函数,属于动态调用的过程,在编译的时候并不能决定真正调用哪个函数,只有在真正运行的时候才会根据函数的名称找到对应的函数来调用;
在编译阶段,OC可以调用任何函数,即使这个函数并未实现,只要声明过就不会报错;在编译阶段,C语言调用未实现的函数就会报错。
在程序运行的过程中,动态的创建一个类(比如KVO的底层实现)
在程序运行过程中,动态地为某个类添加属性/方法,可以用于封装框架(想怎么改就怎么改),这也是我们runtime机制的主要运用方向
遍历一个类中所有的成员变量(属性)/所有方法。比如字典转模型:利用runtime遍历模型对象的所有属性,根据属性名从字典中取出对应的值,设置到模型的属性上;还有归档和解档,利用runtime遍历模型对象的所有属性。
我感觉还是有必要看一下理论知识,如果不看跳过---
它是selector(方法选择器)在Objc中的标示(Swift中是Selector类)。Objc在相同的类中不会有命名相同的两个方法。selector对方法名进行包装,以便找到对应的方法实现,它的数据结构:
id 是一个参数类型,它是指向某个类的实例的指针。定义如下:
Class其实是指向objc_class 结构体的指针。objc_class 的数据结构如下:
从 objc_class 可以看到,一个运行时类中关联了它的父类指针、类名、成员变量、方法、缓存以及附属的协议。
其中 objc_ivar_list 和 objc_method_list 分别是成员变量列表和方法列表:
由此可见,我们可以动态修改 *methodList 的值来添加成员方法,这也是 Category 实现的原理,同样解释了 Category 不能添加属性的原因。
objc_ivar_list 结构体用来存储成员变量的列表,而 objc_ivar 则是存储了单个成员变量的信息;同理,objc_method_list 结构体存储着方法数组的列表,而单个方法的信息则由 objc_method 结构体存储。
值得注意的是,objc_class 中也有一个 isa 指针,这说明 Objc 类本身也是一个对象。为了处理类和对象的关系,Runtime库创建了一种叫做 Meta Class(元类) 的东西,类对象所属的类就叫做元类。元类表述了类对象本身所具备的元数据。
我们所熟悉的类方法,就源自于 Meta Class。我们可以理解为类方法就是类对象的实例方法。每个类仅有一个类对象,而每个类对象仅有一个与之相关的元类。
当你发出一个类似 [NSObject alloc] (类方法)的消息时,实际上,这个消息被发送给了一个类对象,这个类对象必须是一个元类的实例,而这个元类同时也是一个根元类的实例,所有元类的isa指针最终都指向根元类。
所以当 [NSObject alloc] 这条消息发送给类对象的时候,运行时代码 objc_msgSend() 会去它元类中查找能够响应消息的方法实现,如果找到了,就会对这个类对象执行方法调用。
Method 是一个方法结构体的指针:
objc_method 存储了方法名,方法类型和方法实现:
方法名类型为SEL
方法类型 method_types 是个char指针,存储方法的参数类型和返回值类型
method_imp 指向了方法的实现,本质是一个函数指针
Ivar 是表示成员变量的类型。
IMP在objc.h中的定义是:
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-58701-1.html
差距主要在单舰吨位