Runtime的使用7 【动态添加方法】

      首先创建一个Dog类,然后添加两个C语言方法。

//这是一个 C 语言的函数,它至少包含了 self 和 _cmd 两个参数(self 代表着函数本身,而 _cmd 则是一个 SEL 数据体,包含了具体的方法地址)
void eat(id self,SEL sel){
    
    NSLog(@"%@ %@",self,NSStringFromSelector(sel));
}


void run(id self,SEL sel , NSString *band){
    
    NSLog(@"%@ %@ %@",self,NSStringFromSelector(sel),band);
}


      然后在m文件中重写resolveInstanceMethod或者resolveClassMethod方法。看情况而定。

   两个方法的区别在于需要添加的是静态方法还是实例方法。

   + (BOOL)resolveInstanceMethod:(SEL)sel

   + (BOOL)resolveClassMethod:(SEL)sel

       Objective-C中,正常的调用方法是通过消息机制(message)来实现的,那么如果类中没有找到发送的消息方法,系统就会进入找不到该方法的处理流程中,如果在这个流程中,我们加入我们所需要的新方法,就能实现运行过程中的动态添加了。这个流程或者说机制,就是 Objective-C Message Forwarding

 

// 静态方法
+ (BOOL)resolveInstanceMethod:(SEL)sel {
    
    if (sel == NSSelectorFromString(@"eat")) {
        // 注意:这里需要强转成IMP类型
        class_addMethod(self, sel, (IMP)eat, "v@:");
        return YES;
    }
    
    if (sel  ==  @selector(run:)) {
        
        class_addMethod(self, sel, (IMP)run, "v@:");
        return YES;
    }
    
    // 先恢复, 不然会覆盖系统的方法
    return [super resolveInstanceMethod:sel];
}


//动态方法
+ (BOOL)resolveClassMethod:(SEL)sel{
    
    return [super resolveClassMethod:sel];
}


    然后调用一下检查一下成果

    Dog *dog = [[Dog alloc] init];
    
    // 没有实现eat方法,可以通过performSelector调用,但是会报错。
    // 动态添加方法仅仅是警告但是不会报错。已经已经runtime实现了这个方法。
    
    [dog performSelector:@selector(eat)];
    [dog performSelector:@selector(run:) withObject:@"跑起来"];

上面我们代码运行会有个警告。好尴尬。下面方法,可以去掉





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值