ios

- (IMP)methodForSelector:(SEL)aS

2015-09-28  本文已影响2452人  ParkinWu

这个方法是获取某个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,就是这个原理
上一篇 下一篇

猜你喜欢

热点阅读