一,runtime的简介:
runtime简称运行时。Object-C就是运行时机制也就是运行时候的一些机制。其中最主要的就是消息机制。
1>和C语言的区别
C语言:函数的调用在编译的时候就决定了调用那个函数。
OC语言:它的调用是个动态调用过程,也就是说在编译阶段并不能决定真正调用哪个函数,只有在真正运行的时候
才会根据函数的名称找到对应的函数来调用。
所以综合如下:
1.在编译阶段,C语言在调用未实现的函数就会报错。
2.在编译阶段,OC可以调用任何函数,即使这个函数并未实现,只要声明就不会报错。
2>runtime在iOS实际开发中它的价值毋庸置疑,能为我们实现很多变态的功能,并且它比较偏底层,运行速度也是很快的。
所以后面一点点的来进行讲解,首先聊下它的消息机制,因为OC的底层实现就是通过runtime来实现的,且其任何方法的调用
本质就是发送消息。
二,runtime消息机制
1.使用消息机制的前提,必须导入
#import <objc/message.h>
2.可以在终端把OC转化成C++代码,使用命令clang -rewrite-objc main.m
三,看下具体的操作。
1.为了简便,先用命令行创建一个项目
2.在main函数里面我们输入下面的代码
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
id obj = [NSObject alloc];
obj = [obj init];
}
return 0;
}
3.打开终端,进入main.m所在的目录下,然后输入命令:clang -rewrite-objc main.m
运行完成后,可以看到在main.m所在的文件夹中生成了main.cpp文件
4.双击打开,我们可以发现生成了很多代码,我们找到最主要的代码,搜索
@autoreleasepool,可以发现我们熟悉的代码,如下图所示
5.对代码进行简化,因为代码前面加上类型,是有强行类型转换的作用的,不防我们删掉来看,代码如下
id obj = objc_msgSend(objc_getClass("NSObject"), sel_registerName("alloc"));
obj = objc_msgSend(obj, sel_registerName("init"));
6.对比我们很容易就得出对应关系。
三,对上面所用的函数进行解答
方法调用的本质就是让对象发送消息
//此方法为发送消息的方法
//第一个参数:发送消息的对象
//第二个参数:发送对象实现方法的名称
objc_msgSend(<#id self#>, <#SEL op, ...#>)
//获取一个类对象
objc_getClass(<#const char *name#>)
//注册一个方法
sel_registerName(<#const char *str#>)
需要强调一点的是获取对象和注册方法函数里面的参数不是随便写的,而是系统内部存在这样的才行,否则会报错