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

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

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

在学 Runtime 之前你绝对不理解为什么是发送消息而不是调用。“调用”时确定的,而最终要执行哪段代码是不确定的。

有可能现在还不懂这个确定不确定的到底是什么意思。这个问题暂时可以先留着,我们先看看我们的方法“调用”在runtime转化成C或C++的时候到底变成什么样子了。

首先我们新建一个Mac OS X 命令行工程(这个在我们学习OC之前学习C的时候有可能用到过的)

这里创建一个命令行工程完全是为了简单。

这样我们就获得了一个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的实践——方法交换

时间: 2024-11-10 02:26:04

Runtime的初步认识——消息机制的相关文章

runtime总结二之消息机制(包括消息转发,消息交换的黑魔法)

runtime的消息机制 前面提到过编译器最终会把我们的消息发送转化为函数调用 消息发送 [object sendMassage] 首先编译器会在运行时将上面的例子转化为objc_msgSend(obj,@selector(sendMassage))这个函数,转换的时候除了方法本身的参数之外,还有两个隐藏的参数一个是id类型的,代表对象的类型,还是一个是SEL类型的,是函数对应的方法的编号,接下来就会按照下面的流程来调用这个方法 通过obj的isa指针找到其所对应的类. 通过SEL先去类的cac

Runtime那些事儿(消息机制)

一.关于runtime 之前在项目中有遇到过用runtime解决改变全局字体的问题,所以再一次感受到了runtime黑魔法的强大,趁现在有机会分享一下对runtime的一些理解.在对象调用方法是Objective-C中经常使用的功能,也就是消息的传递,而Objective-C是C的超集,所以和C不同的是,Objective-C使用的是动态绑定,也就是runtime.Objective-C的消息传递和消息机制也就不多说了,今天主要说的是动态方法,也就是函数的调用. 二.相关的几个函数 下面一张图详

Runtime的初步认识——结构体与类

Runtime的初步认识 Runtime的初步认识 Runtime介绍 类与结构体的关系 结构体解析 结构体的作用 Runtime介绍 学习一个东西至少要先知道它是个啥,你一定听说过"运行时是 Objective-C 的一个特色",这里的"运行时"就是指 runtime 了. runtime是在自 iOS 平台开放并基于 Objective-C 语言开发后的一个编程语言上的高级技术. 学习runtime的目的并不是为了开发,而是让你更好的理解 Objective-C

iOS开发runtime学习:一:runtime简介与runtime的消息机制

一:runtime简介:也是面试必须会回答的部分 二:runtime的消息机制 #import "ViewController.h" #import <objc/message.h> #import "Person.h" /* 总结: 1: runtime:必须要导入头文件 <objc/message.h>,此头文件中已经引入了<objc/runtime.h> 任何方法调用本质:发送一个消息,用runtime发送消息.OC底层实现

Objective-C总Runtime的那点事儿(一)消息机制

Objective-C总Runtime的那点事儿(一)消息机制 RunTime简称运行时.就是系统在运行的时候的一些机制,其中最主要的是消息机制.对于C语言,函数的调用在编译的时候会决定调用哪个函数( C语言的函数调用请看这里 ).编译完成之后直接顺序执行,无任何二义性.OC的函数调用成为消息发送.属于动态调用过程.在编译的时候并不能决定真正调用哪个函数(事实证明,在编 译阶段,OC可以调用任何函数,即使这个函数并未实现,只要申明过就不会报错.而C语言在编译阶段就会报错).只有在真正运行的时候才

NSObject头文件解析 / 消息机制 / Runtime解读 (二)

本章接着NSObject头文件解析 / 消息机制 / Runtime解读(一)写 给类添加属性: BOOL class_addProperty(Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount) 其中有一个参数我们再在上一篇中提到过 typedef struct { const char *name;           /**< The na

NSObject头文件解析 / 消息机制 / Runtime解读 (一)

NSObject头文件解析 当我们需要自定义类都会创建一个NSObject子类, 比如: #import <Foundation/Foundation.h> @interface ClassA : NSObject @end 那么NSObject里面具体有什么呢? 我们点到它的头文件里面去看看 @interface NSObject <NSObject> { Class isa OBJC_ISA_AVAILABILITY; //每个NSObject对象都拥有一个Class类作为成员

Objective-C总Runtime的那点事儿(一)消息机制【转】

RunTime简称运行时.就是系统在运行的时候的一些机制,其中最主要的是消息机制.对于C语言,函数的调用在编译的时候会决定调用哪个函数( C语言的函数调用请看这里 ).编译完成之后直接顺序执行,无任何二义性.OC的函数调用成为消息发送.属于动态调用过程.在编译的时候并不能决定真正调用哪个函数(事实证明,在编 译阶段,OC可以调用任何函数,即使这个函数并未实现,只要申明过就不会报错.而C语言在编译阶段就会报错).只有在真正运行的时候才会根据函数的名称找 到对应的函数来调用. 那OC是怎么实现动态调

RunTime(消息机制) + RunTime(消息转发)

一.消息机制 1.在viewDidLoad中直接用 performSelector:@selector(doSomething) 来调用doSomething方法时,会发现找不到这个方法而奔溃.此时,我们可以在resolveInsantanceMethod:(SEL)see 方法中获取这个所有在运行时阶段的方法,在这个方法中只需要判断一下,将这个方法获取,并且运用Runtime 的 class_addMethod 的方法来将方法和响应函数绑定,进而达到为某一个类添加方法的目的. - (void)