IMP是”implementation”的缩写,存储的是OC实现方法代码块的地址。一般通过[obj method:params] 或者 objc_msgSend()向对象发送消息,然后OC的runtime机制会通过SEL找到对应的IMP指针,继而调用它所指向的函数实现。
一、objc_method数据结构
进入runtime.h的内部,可以看到objc_method的数据结构如下:
struct objc_method {
SEL _Nonnull method_name OBJC2_UNAVAILABLE; //方法名
char * _Nullable method_types OBJC2_UNAVAILABLE; //方法类型
IMP _Nonnull method_imp OBJC2_UNAVAILABLE; //具体方法实施的指针
} OBJC2_UNAVAILABLE;
对应的获取:
SEL method_getName(Method method);
IMP method_getImplementation(Method method);
const char * ivar_getTypeEncoding(Ivar ivar);
二、获取当前方法的默认IMP
NSObject对象提供了两个方法来获取对应的IMP指针
- (IMP)methodForSelector:(SEL)aSelector;
- (IMP)instanceMethodForSelector:(SEL)aSelector;
1.使用methodForSelector方法(methodForSelector返回的IMP是default IMP,即发送消息时会调用的IMP)
(1)若向类(class)发送消息,则aSelector应该是类方法(class method);
(2)若向实例对象(instance)发送消息,则aSelector应该为实例对象方法(instance method)。
2.使用instanceMethodForSelector可向类请求实例方法的IMP。
获取当前方法的IMP,可使用self对象和隐含的_cmd参数。
隐含参数:尽管这些参数不是显式声明的,源码仍能引用它们(正像它能引用接收对象的实例变量一样)。
_cmd 是隐藏的参数,表示当前方法的selector。
作用:
1、获取当前被调用方法:NSStringFromSelector(_cmd)。
2、在运行时时使用:在某个分类方法里为对象动态添加属性,由于_cmd是在编译时候(compile - time)就可以确定的值,因此可以直接使用。
IMP current = [[self class] instanceMethodForSelector:_cmd];
链接:
1.https://www.jianshu.com/p/a757adc81a96
2.https://www.cnblogs.com/someonelikeyou/p/8560156.html
3.https://juejin.im/post/6844903939586916366
网友评论