iOS IMP 与 SEL
2019-06-22 本文已影响0人
7890陈
IMP 官方文档
指向方法实现开始的指针
id (*IMP)(id, SEL, ...)
// 描述
该数据类型是指向实现该方法的函数的开始的指针。
此函数使用标准C调用约定作为当前CPU体系结构的实现。
第一个参数是指向self的指针(即该类的特定实例的内存,或类方法的指向元类的指针)。
第二个参数是方法选择器。
SEL 官方文档
定义表示方法选择器的不透明类型
typedef struct objc_selector *SEL;
// 描述
方法选择器用于在运行时表示方法的名称。
方法选择器是一个已在Objective-C运行时注册(或“映射”)的C字符串 。
编译器生成的选择器在加载类时由运行时自动映射。
您可以在运行时添加新的选择器,并使用sel_registerName函数检索现有的选择器 。
使用选择器时,必须使用sel_registerName或Objective-C编译器指令@selector()返回的值。
不能简单地将C字符串转换为SE。
sel_registerName
SEL sel = sel_registerName("test1");
[self performSelector:sel];
- (void)test1
{
NSLog(@"1");
}
// 打印结果:1
通过SEL 找到对应的IMP并调用
SEL sel = @selector(test1);
IMP imp = [self methodForSelector:sel];
SEL sel2 = @selector(test4);
IMP imp2 = [self methodForSelector:sel2];
objc_msgSend(self,sel,imp);
objc_msgSend(ViewController.class, sel2,imp2);
- (void)test1
{
NSLog(@"1");
}
+ (void)test4
{
NSLog(@"4");
}
// 打印结果为 1 、4
// 使用 objc_msgSend 需添加头文件 #import <objc/message.h>
// 还有在 Build Settings 中找到 Enable Strict Checking of objc_msgSend Calls 设置为NO
methodForSelector 官方文档
定位并返回接收方方法实现的地址,以便将其作为函数调用
- (IMP)methodForSelector:(SEL)aSelector;
// aSelector
一个选择器,它标识返回实现地址的方法。
选择器必须是有效且非空的。
如果有疑问,在将选择器传递给 methodForSelector: 之前,使用respondsToSelector:方法进行检查。
// return value
接收者实现选择器的地址。
// Discussion
如果接收方是实例,则aSelector应引用实例方法;
如果接收器是一个类,它应该引用一个类方法
respondsToSelector 官方文档
返回一个布尔值,该值指示接收类是否响应给定的selector
- (BOOL)respondsToSelector:(SEL)aSelector;
// 返回值
如果接收类响应aSelector消息,则为YES,否则为NO