- (IMP)methodForSelector:(SEL)aSelector和+ (IMP)instanceMethodForSelector:(SEL)aSelector

这个方法是获取某个SEL的IMP
问题来了,什么是SEL,什么是IMP?

1. SEL

Objective-C是动态语言,动态体现在可以在运行的时候修改所执行的方法,可以把一个对象的所有方法看成一张表,SEL就可以看成表中每一条的索引,根据方法名来生成对应的SEL,所以OC中不同的方法名就对应不同的方法

SEL1 SEL2 SEL3 ...
IMP1 IMP2 IMP3 ...

2. IMP

IMP是真正的函数指针,这是其定义
typedef id (*IMP)(id, SEL,... );
它指向一个真正的函数地址

我们借助- (IMP)methodForSelector:(SEL)aSelector来证明这一点

3. - (IMP)methodForSelector:(SEL)aSelector

这个方法可以根据一个SEL,得到该方法的IMP(函数指针)
假设:如果返回的是个函数指针,那么我们应该能够直接使用imp();进行调用。
实验:

- (void)viewDidLoad {
    [super viewDidLoad];
    IMP imp = [self methodForSelector:@selector(sayHi)];
    imp();

}
- (void)sayHi {
    NSLog(@"hello world");
}

控制台打印:

2015-09-28 09:51:13.132 MethodForSelector[755:215807] hello world

需要注意的是- (IMP)methodForSelector:(SEL)aSelector参数aSelector即使是私有方法,即在.h文件中没有暴露接口也会调用成功

4. + (IMP)instanceMethodForSelector:(SEL)aSelector

这个方法是个类方法,返回的是该方法(aSelector)的真正的函数地址

总结:

  1. SEL是索引
  2. IMP是真正的函数
  3. 既然我们SEL和IMP是映射关系,那么我们就可以改变这个映射关系,method swizzle,就是这个原理
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容