在这里需要先了解几个概念
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开始寻找。
网友评论