iOS底层系列之<16>--Runtime(四)消息机制之第二阶段:动态方法解析

第二阶段:动态方法解析

  • 流程图
    在这里插入图片描述

  • 代码展示

void c_other(id self, SEL _cmd) {
    NSLog(@"%s",__func__);
}

+ (BOOL)resolveInstanceMethod:(SEL)sel {
    NSLog(@"%s", __func__);
    if (sel == @selector(test)) {
        Method otherMethod = class_getInstanceMethod(self, @selector(other));
        class_addMethod(self, sel, (IMP)c_other, "v16@0:8");
        
        return YES;
    }
    return [super resolveInstanceMethod:sel];
}
  • 重点详解下class_addMethod方法,我看网上别人的很多博客,博主自己都没搞明白到底是怎么回事!希望我下面的总结能帮助到你!
class_addMethod(Class  _Nullable __unsafe_unretained cls,
                SEL  _Nonnull name,
                IMP  _Nonnull imp,
                const char * _Nullable types)
                        
第一个参数:如果是实例对象方法,这里就传类对象;
     		   (是自己,就传self,是别的类,就传别的类)
     	       如果是类对象方法,这里就传元类对象;
     	       (是自己,就传元类对象object_getClass(self)是别的类,就传别的元类对象object_getClass(otherClass))

第二个参数:SEL 类型即可
第三个参数:如果是C语言函数,就传(IMP)C语言函数名
          如果是OC函数,先通过Method otherMethod = class_getClassMethod(self, @selector(other1:));获取方法名
          再传method_getImplementation(otherMethod)
第四个参数:[请先参考这篇文章第2章节](https://blog.csdn.net/JH_Cao/article/details/122358985)
		  void类型,传先传一个v
	      因为OC方法都有两个隐藏的参数(id self, SEL _cmd),
	      所以再传@,表示id类型或一个object(即对象类型)
		  再传冒号一个: 表示SEL类型
  • 举例说明
    1.添加C语言函数
void c_other() {
    NSLog(@"%s",__func__);
}

+ (BOOL)resolveInstanceMethod:(SEL)sel {
    if (sel == @selector(test)) {
        class_addMethod(self, sel, (IMP)c_other, "v@:");
        return YES;
    }
    return [super resolveInstanceMethod:sel];
}

2.添加OC对象方法

- (void)other {
    NSLog(@"%s",__func__);
}
+ (BOOL)resolveInstanceMethod:(SEL)sel {
    if (sel == @selector(test)) {
        Method otherMethod = class_getInstanceMethod(self, @selector(other));
        class_addMethod(self, sel, method_getImplementation(otherMethod), "v@:");
        return YES;
    }
    return [super resolveInstanceMethod:sel];
}

3.添加OC类方法

+ (void)other1:(NSString *)str {
    NSLog(@"%s",__func__);
}
+ (BOOL)resolveClassMethod:(SEL)sel {
    if (sel == @selector(test1)) {
        Method otherMethod = class_getClassMethod(self, @selector(other1:));
        class_addMethod(object_getClass(self), sel, method_getImplementation(otherMethod), "v@:@"); // NSString 是一个对象类型
        
        return YES;
    }
    return [super resolveClassMethod:sel];
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值