iOS IMP

作者: 想飞的菜鸟 | 来源:发表于2020-10-12 11:20 被阅读0次

    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

    相关文章

      网友评论

          本文标题:iOS IMP

          本文链接:https://www.haomeiwen.com/subject/qaosuktx.html