Runtime的初步认识——消息机制

来源:互联网 发布:5g网络wifi什么意思 编辑:程序博客网 时间:2024/04/20 00:53

之前写过一篇《Runtime的初步认识》,读过的小伙伴们应该对OC中的类与C中的结构体的关系有了一定的了解。这篇文章就先介绍一下OC中的方法是如何“调用”的。这就是OC的另一个机制——消息机制。

OC 的消息机制是指,在外部需要执行某个对象的方法时,使用的方式是“发送消息”而不是“调用”。

在学 Runtime 之前你绝对不理解为什么是发送消息而不是调用。“调用”时确定的,而最终要执行哪段代码是不确定的。
有可能现在还不懂这个确定不确定的到底是什么意思。这个问题暂时可以先留着,我们先看看我们的方法“调用”在runtime转化成C或C++的时候到底变成什么样子了。

首先我们新建一个Mac OS X 命令行工程(这个在我们学习OC之前学习C的时候有可能用到过的)新建Mac OS X 命令行工程
这里创建一个命令行工程完全是为了简单。

这样我们就获得了一个main.m文件

然后我们在main.m文件中写一句最简单的实例化对象的代码

id object = [NSObject alloc];object = [obj init];

保存一下之后用终端cd到这个文件目录下(此处可以打开终端,输入cd空格之后把那个文件夹拖入终端自动生成路径按回车~)

然后执行clang编译命令把main.m文件编译成C++

clang -rewrite-objc main.m

然后你就可以得到一个 main.cpp 文件,这就是 C++ 文件了。

打开这个文件,到文件的最后,你可以找到你写的 main 函数,看看它有什么内容

id object = ((NSObject *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("NSObject"), sel_registerName("alloc"));        object = ((id (*)(id, SEL))(void *)objc_msgSend)((id)object, sel_registerName("init"));

似乎看不太懂,所以要简化一下(去掉一些属性声明,不影响实际逻辑)

id object = objc_msgSend(objc_getClass("NSObject"), sel_registerName("alloc"));object = objc_msgSend(object, sel_registerName("init"));

与OC代码对应就是

id object = [NSObject alloc];//编译成C++后id object = objc_msgSend(objc_getClass("NSObject"), sel_registerName("alloc"));
object = [object init];//编译成C++后object = objc_msgSend(object, sel_registerName("init"));

这里

objc_getClass("NSObject") 通过字符串获取Class

sel_registerName("init") 通过字符串获取方法SEL

objc_msgSend(id, SEL) 消息发送的方法

  • 首先通过一个字符串创建一个类的结构体指针
  • 然后通过一个字符串创建一个类方法的结构体指针
  • 最后向类结构体发送一个消息,得到一个结果。

这就是一个最简单的消息机制,把面向对象变为面向过程。

Runtime的实践——给一个类添加属性(关联对象)
Runtime的实践——方法交换

2 0
原创粉丝点击