美文网首页
Runtime 运行时之三:方法与消息

Runtime 运行时之三:方法与消息

作者: Django_Monstar | 来源:发表于2016-11-30 18:07 被阅读10次

基础数据类型

SEL

又叫选择器,是表示一个方法的selector的指针,其定义如下:

typedef struct objc_selector *SEL;

objc_selector结构体的详细定义没有在<objc/runtime.h>头文件中找到。方法的selector用于表示运行时方法的名字.Objective-C在编译时会依据每一个方法的名字,参数序列,生成一个唯一的整型标识(Int类型的地址),这个标识就是SEL
两个类之间,只要方法名相同,那么方法的SEL就是一样的.每个方法对应着一个SEL,所以在Objective-C同一个类和子类中不能存在2个同名的方法,即使参数类型不同也不行。相同的方法只能对应一个SEL。
当然不同的类可以拥有相同的selector,因为不同的类的实例对象执行相同的selector时,会在各自的方法列表中去寻找对应的IMP。
SEL实际上就是根据方法名hash化了的一个字符串,SEL只是一个指向方法的指针(准确的说,只是一个根据方法名hash化了的KEY值,能唯一代表一个方法)。

IMP

实际上是一个函数指针,指向方法实现的首地址

id(*IMP)(id SEL,...)

第一个参数指向self的指针(如果是实例方法,则是类实例的内存地址,如果是类方法,则是指向元类的指针),第二个参数是方法选择器(selector),接下来是方法的实际参数列表。

Method

Method用于表示类定义中的方法

typedef struct objc_method *Method;
struct objc_method{
SEL method_name OBJC2_UNAVAILABLE;//方法名
char *method_type OBJC2_UNAVAILABLE;
IMP method_imp OBJC2_UNAVAILABLE;//方法实现
}

我们可以看到该结构体中包含一个SEL和IMP,实际上相当于在SEL和IMP之间作了一个映射。有了SEL,我们便可以找到对应的IMP,从而调用方法的实现代码。具体操作流程我们将在下面讨论。

方法
// 调用指定方法的实现
id method_invoke ( id receiver, Method m, ... );

// 调用返回一个数据结构的方法的实现
void method_invoke_stret ( id receiver, Method m, ... );

// 获取方法名
SEL method_getName ( Method m );

// 返回方法的实现
IMP method_getImplementation ( Method m );

// 获取描述方法参数和返回值类型的字符串
const char * method_getTypeEncoding ( Method m );

// 获取方法的返回值类型的字符串
char * method_copyReturnType ( Method m );

// 获取方法的指定位置参数的类型字符串
char * method_copyArgumentType ( Method m, unsigned int index );

// 通过引用返回方法的返回值类型字符串
void method_getReturnType ( Method m, char *dst, size_t dst_len );

// 返回方法的参数的个数
unsigned int method_getNumberOfArguments ( Method m );

// 通过引用返回方法指定位置参数的类型字符串
void method_getArgumentType ( Method m, unsigned int index, char *dst, size_t dst_len );

// 返回指定方法的方法描述结构体
struct objc_method_description * method_getDescription ( Method m );

// 设置方法的实现
IMP method_setImplementation ( Method m, IMP imp );

// 交换两个方法的实现
void method_exchangeImplementations ( Method m1, Method m2 );
方法调用流程

在Objective-C中,消息直到运行时才绑定到方法实现上。编译器会将消息表达式[receiver message]转化为一个消息函数的调用,即objc_msgSend。这个函数将消息接收者和方法名作为其基础参数

相关文章

网友评论

      本文标题: Runtime 运行时之三:方法与消息

      本文链接:https://www.haomeiwen.com/subject/gsutmttx.html