- RunTime简称运行时。就是系统在运行的时候的一些机制,其中最主要的是消息机制。对于C语言,函数的调用在编译的时候会决定调用哪个函数( C语言的函数调用请看这里 )。编译完成之后直接顺序执行,无任何二义性。OC的函数调用成为消息发送。属于动态调用过程。在编译的时候并不能决定真正调用哪个函数(事实证明,在编 译阶段,OC可以调用任何函数,即使这个函数并未实现,只要申明过就不会报错。而C语言在编译阶段就会报错)。只有在真正运行的时候才会根据函数的名称找 到对应的函数来调用。
区别:
C-->编译时决定使用哪一个函数;
OC-->运行时选择使用哪一个函数;
在我们平时所写的Objective-C代码执行的时候,最后都会转换成Runtime的C代码。
举例:
OC代码:
HJTPerson *person = [[HJTPerson alloc]init];
[person playGame];
Runtime:
objc_msgSend(objc_msgSend(“MJPerson” , “alloc”), “init”)
objc_msgSend(person,@selector(playGame));
//如果有参数则为
objc_msgSend(person,@selector(playGame),arg1,arg2);
@selector (playGame):这是一个SEL方法选择器。
SEL其主要作用是快速的通过方法名字(makeText)查找到对应方法的函数指针,然后调用其函数。
SEL其本身是一个Int类型的一个地址,地址中存放着方法的名字。
对于一个类中。每一个方法对应着一个SEL。
所以iOS类中不能存在2个名称相同 的方法,即使参数类型不同,因为SEL是根据方法名字生成的,相同的方法名称只能对应一个SEL。
消息发送以后,查找方法的过程:
首先,编译器将代码[person playGame]转化为objc_msgSend(person, @selector (playGame));
在objc_msgSend函数中,首先通过person的isa指针找到person对应的class。(当一个对象被创建时,内存布局中的第一个元素是指向类结构的指针isa。通过isa指针,一个对象可以访问它的类结构,进而访问继承的类结构)
在Class中先去cache中通过SEL查找对应函数method(猜测cache中method列表是以SEL为key通过hash表来存储的,这样能提高函数查找速度).
若 cache中未找到,再去methodList中查找,若methodlist中未找到,则取superClass中查找。
若能找到,则将method加入到cache中,以方便下次查找,并通过method中的函数指针跳转到对应的函数中去执行。
Runtime中需要用到的函数:
objc_msgSend : 给对象发送消息
class_copyMethodList : 遍历某个类所有的方法
class_copyIvarList : 遍历某个类所有的成员变量