Objective-C Runtime机制 - 方法的调用

2018-11-27  本文已影响18人  9d8c8692519b
在这里需要先了解几个概念

SEL

SEL是objc_selector类型指针,是根据特定规则生成的方法的唯一标识。需要注意的是,只要方法名相同,生成的SEL就相同,与这个方法属于哪个类没有关系。

typedef struct objc_selector *SEL;

IMP

如果说,SEL是方法名,那么IMP就是方法的实现。IMP指针定义了一个方法的入口,指向了实现方法的代码块的内存地址。

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

objc_method

在objc中,方法实质上是一个objc_method指针。其中,method_name相当于objc_method的hash值,runtime通过method_name找到相应的方法入口(method_imp),从而执行方法的代码块。

struct objc_method {
SEL method_name OBJC2_UNAVAILABLE;
char *method_types OBJC2_UNAVAILABLE;
IMP method_imp OBJC2_UNAVAILABLE;
} OBJC2_UNAVAILABLE;

调用一个方法时具体做了什么?

在Objective-C中,方法的调用采用如下方式:

[object methodWithArg:arg];

在编译期间,以上代码会被转化为

objc_msgSend(object, methodWithArg, arg)

可以把它看作是发送消息的过,其中object为消息的接收体,它可能是一个对象,也可能是一个类。若为对象,则是实例方法(- 方法);反之,则是类方法(+方法)。mehodWithArg、arg是具体的消息内容。
object接收到消息之后,若是实例方法,则会从其所属的类Subclass(class)的methodLists去寻找methodWithArg:方法。若未找着,则到其父类Superclass(class)的methodLists中寻找。以此类推,直到根类NSObject,若仍未找着,就crash。
同理,若是类方法,则从对象所属类的meta class开始寻找。

上一篇 下一篇

猜你喜欢

热点阅读