这个方法是获取某个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)的真正的函数地址
总结:
- SEL是索引
- IMP是真正的函数
- 既然我们SEL和IMP是映射关系,那么我们就可以改变这个映射关系,method swizzle,就是这个原理