一个对象的方法像这样[obj foo]
,编译器转成消息发送objc_msgSend(obj, foo),objec_msgSend的方法定义如下:
OBJC_EXPORT id objc_msgSend(id self, SEL op, ...)
- 系统首先找到消息的接收对象,然后通过对象的
isa
找到它的类。 - 在它的类中查找
method_list
,是否有selector
方法。 - 没有则查找父类的
method_list
。 - 找到对应的
method
,执行它的IMP
。 - 转发
IMP
的return
值。
我们看看对象(object),类(class),方法(method)这几个的结构体:
//对象
struct objc_object {
Class isa OBJC_ISA_AVAILABILITY;//
isa
指针指向类对象,};
//类
struct objc_class {
Class isa OBJC_ISA_AVAILABILITY;//
isa
指针指向的结构体创建,类对象的isa
指针指向的我们称之为元类(metaclass
),元类的isa
指针又指向了自己。SEL originalSelector = @selector(viewDidLoad);
Method originalMethod = class_getInstanceMethod(class,originalSelector);
class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
method_exchangeImplementations(originalMethod, swizzledMethod);
class_getMethodImplementation(objc_getMetaClass("A"),
SEL name
);
//获取类方法的实现
class_getMethodImplementation(objc_getClass("A"),
SEL name
);//获取实例方法的实现
Method class_getClassMethod(Class cls, SEL name);//获取类方法的方法体
Method class_getInstanceMethod(Class cls, SEL name);//获取实例方法的方法体
IMP method_getImplementation(Method m);//根据方法体
获取IMP地址
Method
和我们平时理解的函数是一致的,就是表示能够独立完成一个功能的一段代码,其实
selector
就是个映射到方法的C
字符串,你可以用 Objective-C
编译器命令@selector()
或者 Runtime
系统的sel_registerName
函数来获得一个 SEL
类型的方法选择器。typedef id (*IMP)(id, SEL, ...);
IMP
的定义就是指向最终实现程序的内存地址的指针。
消息转发完整流程:
_objc_msgForward(id receiver,SEL sel, ...) 调用此方法进行消息转发,即使实现了该方法也会转发

super
关键字接收到消息时,编译器会创建一个 objc_super
结构体:
struct objc_super { id receiver; Class class; };