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
上一篇下一篇

猜你喜欢

热点阅读