selector

iOS 方法底层探索-SEL方法编号编译加载

2020-09-29  本文已影响0人  想飞的菜鸟

SEL : 类成员方法的指针,但不同于C语言中的函数指针,函数指针直接保存了方法的地址,但SEL只是方法编号。

每一个继承于NSObject的类都能自动获得runtime的支持。在这样的一个类中,有一个isa指针,指向该类定义的数据结构体,这个结构体是由编译器编译时为类(需继承于NSObject)创建的.在这个结构体中有包括了指向其父类类定义的指针以及 dispatch table. dispatch table是一张SEL和IMP的对应表。dispatch table 仅仅包含了当前类的selector和MethodIMP的地址。

方法编号SEL最后还是要通过dispatch table表寻找到对应的IMP,IMP就是一个函数指针,然后执行这个方法。

1.获取方法编号
(1)SEL methodID = @selector(方法名);
(2)SEL methodID = NSSelectorFromString(methodName);
注:@selector是查找当前类(含子类)的方法。

2.通过方法编号执行该编号的方法
[self performSelector:methodID withObject:nil];

3.通过方法编号获取该编号的方法名
NSString*methodName = NSStringFromSelector(methodID);

4.通过方法编号获得IMP指针
IMP methodPoint = [self methodForSelector:methodID];

5.执行IMP
void (*func)(id, SEL, id) = (void *)imp;
func(self, methodName,param);

有了SEL这个中间过程,我们可以针对方法编号和IMP指针映射做操作,也就是说我们可以一个SEL指向不同的函数指针,这样就可以完成一个方法名在不同时候执行不同的函数体。另外可以将SEL作为参数传递给不同的类执行。也就是说我们某些业务我们只知道方法名但需要根据不同的情况让不同类执行的时候,SEL可以帮助我们实现。

上一篇下一篇

猜你喜欢

热点阅读