Objective-C Runtime整理(方法和消息)

本文介绍了Objective-C运行时的基础概念,包括SEL、IMP和Method。详细解释了SEL作为方法选择器的作用,IMP作为方法实现的指针,以及Method如何描述类中的方法。此外,还提供了与方法操作相关的API介绍。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基础数据类型

SEL

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

typedef struct objc_selector *SEL;

方法的selector用于表示运行时方法的名字,OC在编译时,会依据每一个方法的名字、参数序列,生成一个唯一的整数标识(Int类型的地址),就是SEL。

SEL sel1 = @selector(method1);
NSLog(@"sel : %p", sel1);

//输出
2014-10-30 18:40:07.518 RuntimeTest[52734:466626] sel : 0x100002d72

两个类之间,不管它们是父类与子类的关系,还是之间没有这种关系,只要方法名相同,那么方法的SEL就是一样的。每一个方法都对应着一个SEL。所以在Objective-C同一个类(及类的继承体系)中,不能存在2个同名的方法,即使参数类型不同也不行。相同的方法只能对应一个SEL。

我们可以在运行时添加新的selector,也可以在运行时获取已存在的selector,我们可以通过下面三种方法来获取SEL:

  • sel_registerName函数
  • Objective-C编译器提供的@selector()
  • NSSelectorFromString()方法

IMP

IMP实际上是一个函数指针,指向方法实现的首地址。其定义如下:

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

SEL就是为了查找方法的最终实现IMP的。由于每个方法对应唯一的SEL,因此我们可以通过SEL方便快速准确地获得它所对应的IMP,查找过程将在下面讨论。取得IMP后,我们就可以像调用普通的C语言函数一样来使用这个函数指针了。

通过取得IMP,我们可以跳过Runtime的消息传递机制,直接执行IMP指向的函数实现,这样省去了Runtime消息传递过程中所做的一系列查找操作,会比直接向对象发送消息高效一些。

Method

Method用于表示类定义中的方法,则定义如下:

typedef struct objc_method *Method;

struct objc_method {

    SEL method_name                 OBJC2_UNAVAILABLE;  // 方法名

    char *method_types                  OBJC2_UNAVAILABLE;

    IMP method_imp                      OBJC2_UNAVAILABLE;  // 方法实现

}

struct objc_method_description { SEL name; char *types; };

方法操作API

调用指定方法的实现,返回的是实际实现的返回值。参数receiver不能为空。这个方法的效率会比method_getImplementation和method_getName更快。

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_getReturnType ( 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 );

返回给定选择器指定的方法的名称

const char * sel_getName ( SEL sel );

在Objective-C Runtime系统中注册一个方法,将方法名映射到一个选择器,并返回这个选择器

SEL sel_registerName ( const char *str );

在Objective-C Runtime系统中注册一个方法

SEL sel_getUid ( const char *str );

比较两个选择器

BOOL sel_isEqual ( SEL lhs, SEL rhs );
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值