Runtime全方位装逼指南

475 查看

楔子
Runtime是什么?见名知意,其概念无非就是“因为 Objective-C 是一门动态语言,所以它需要一个运行时系统……这就是 Runtime 系统”云云。对博主这种菜鸟而言,Runtime 在实际开发中,其实就是一组C语言的函数。胡适说:“多研究些问题,少谈些主义”,云山雾罩的概念听多了总是容易头晕,接下来我们直接从代码入手学习 Runtime。

1、由objc_msgSend说开去:
Objective-C 中的方法调用,不是简单的方法调用,而是发送消息,也就是说,其实 [receiver message] 会被编译器转化为: objc_msgSend(receiver, selector),何以证明?新建一个类 MyClass,其.m文件如下:

使用 clang 重写命令:

然后在同一目录下会多出一个 MyClass.cpp 文件,双击打开,可以看到 init 方法已经被编译器转化为下面这样:

我们要找的就是它:

objc_msgSend 函数被定义在 objc/message.h 目录下,其函数原型是酱紫滴:

该函数有两个参数,一个 id 类型,一个 SEL 类型。

2、SEL
SEL 被定义在 objc/objc.h 目录下:

其实它就是个映射到方法的C字符串,你可以用 Objective-C 编译器命令 @selector() 或者 Runtime 系统的 sel_registerName 函数来获得一个 SEL 类型的方法选择器。

3、id
与 SEL 一样,id 也被定义在 objc/objc.h 目录下:

id 是一个结构体指针类型,它可以指向 Objective-C 中的任何对象。objc_object 结构体定义如下:

我们通常所说的对象,就长这个样子,这个结构体只有一个成员变量 isa,对象可以通过 isa 指针找到其所属的类。isa 是一个 Class 类型的成员变量,那么 Class 又是什么呢?

4、Class
Class 也是一个结构体指针类型:

ǽ数。胡适说:“多研究些问题,少谈些主义”,云山雾罩的概念听多了总是容易头晕,接下来我们直接从代码入手学习 Runtime。

1、由objc_msgSend说开去:
Objective-C 中的方法调用,不是简单的方法调用,而是发送消息,也就是说,其实 [receiver message] 会被编译器转化为: objc_msgSend(receiver, selector),何以证明?新建一个类 MyClass,其.m文件如下:

使用 clang 重写命令:

然后在同一目录下会多出一个 MyClass.cpp 文件,双击打开,可以看到 init 方法已经被编译器转化为下面这样:

我们要找的就是它:

objc_msgSend 函数被定义在 objc/message.h 目录下,其函数原型是酱紫滴:

该函数有两个参数,一个 id 类型,一个 SEL 类型。

2、SEL
SEL 被定义在 objc/objc.h 目录下:

其实它就是个映射到方法的C字符串,你可以用 Objective-C 编译器命令 @selector() 或者 Runtime 系统的 sel_registerName 函数来获得一个 SEL 类型的方法选择器。

3、id
与 SEL 一样,id 也被定义在 objc/objc.h 目录下:

id 是一个结构体指针类型,它可以指向 Objective-C 中的任何对象。objc_object 结构体定义如下:

我们通常所说的对象,就长这个样子,这个结构体只有一个成员变量 isa,对象可以通过 isa 指针找到其所属的类。isa 是一个 Class 类型的成员变量,那么 Class 又是什么呢?

4、Class
Class 也是一个结构体指针类型:

print-yes notranslate" data-settings=" minimize scroll-always" style=" margin-top: 12px; margin-bottom: 12px; font-size: 13px !important; line-height: 15px !important;">