OC中方法的本质

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

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容