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");