OC中方法的本质

2019-12-13  本文已影响0人  一叶知秋0830

OC中方法的定义

OC中Method 被定义为一个objc_method结构体 指针,在这个结构体中,包含一个 SEL 和一个 IMP。

SEL可以理解为就是一个保存方法名的字符串。需要注意的是SEL只保存了方法名,并最终要根据方法名来查找方法的实现,所以OC中是不支持方法重载的,因为方法重载时两个方法方法名相同而参数列表不同,而SEL只保存了方法名,所以重载的方法会被认为是相同的方法。(Swift是支持方法重载的。)

IMP是一个函数指针,指向方法实现的地址。从IMP的定义可以看出其指向的函数包含一个id类型的返回值,函数至少包含2个参数,第一个参数(id)是接收消息的对象,对于实例方法来说指的是当前对象的地址,对于类方法来说指的是当前类对象的地址;第二个参数SEL就是指调用的方法。后面的省略号是方法的参数列表,所以IMP指针指向的函数的参数个数等于调用的方法的参数个数+2。

typedef struct objc_method *Method;

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

// SEL
typedef struct objc_selector *SEL;

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

OC方法的调用

OC中所有的方法调用都会转化成向对象发送消息,发送消息一般使用的是objc_msgSend函数。可以看到objc_msgSend函数的参数和返回值与IMP指向的函数的参数和返回值是一一对应的。

id objc_msgSend(id self, SEL op, ...);
// 无参数无返回值的方法
- (void)sayHello{
    NSLog(@"Hello!");
}

// 方法调用
[self sayHello];

// 发送消息给无参数无返回值的方法
((void (*)(id, SEL)) objc_msgSend)(self, NSSelectorFromString(@"sayHello"));
// 有参数有返回值的方法
- (NSString *)combineString1:(NSString *)str1 string2:(NSString *)str2{
   return [NSString stringWithFormat:@"%@%@",str1,str2];
}

// 方法调用
[self combineString1:@"111" string2:@"222"];

// 发送消息给有参数有返回值的方法
((NSString *(*)(id, SEL, NSString *, NSString *)) objc_msgSend)(self, NSSelectorFromString(@"combineString1:string2:"), @"111",@"222");

上一篇下一篇

猜你喜欢

热点阅读