runtime - 动态添加方法

作者: 我的梦想之路 | 来源:发表于2016-06-08 23:07 被阅读316次

    动态添加方法:
    动态添加就运用到懒加载
    开发场景:如果一个类方法很多,加载类到内存的时候也比较耗费资源,需要给每个方法生成一个映射表(这个词我也不懂),可以使用动态给某个类添加方法。

     Person *p = [[Person alloc]init];
     //performSelector:即为动态添加方法
     [p performSelector:@selector(eat) withObject:nil];
    // 会报警告,运行后会报错,报的错误是因为你没有在Person类里面实现eat方法
    

    如果你想自己动态添加方法
    首先你要在类中实现代码如下:

    #首先介绍相关的方法,后面再整合
    /**
    处理实例方法
     动态添加方法,首先实现这个resolveInstanceMethod方法
     resolveInstanceMethod调用的情况:当调用了一个没有实现的方法,就会调用resolveInstanceMethod这个方法
     <#sel#>:没有实现的方法
     */
    + (BOOL)resolveInstanceMethod:(SEL)sel{}
    
    // runtime 方法(导入<objc/message.h>)
    class_addMethod(<#__unsafe_unretained Class cls#>, <#SEL name#>, <#IMP imp#>, <#const char *types#>)
    
             <#__unsafe_unretained Class cls#>:表示给哪个类添加  -- self 
             <#SEL name#>:方法编号 即为 方法名 -- 未实现的方法
             <#IMP imp#> :方法的实现,函数入口,函数指针或函数名 --在本类的@implementation 类名 下面
        // 定义一个函数(函数名随便写,IMP要与之一致)
       void tangtang_eat(){
        
        }
    
             <#const char *types#> :方法的类型 ---查看xcode help document文档
     xcode --> help --> document -->搜索runtime --> 方法class_addMethod --> 查看<#const char *types#>用法(也有整个动态添加方法的描述)
    
    
    #根据苹果系统的东西来
    #import "Person.h"
    
    #import <objc/message.h>
    
    @implementation Person
    
    /**
     默认一个方法都有两个参数,self,_cmd,为隐式参数,不显示
     self :方法的调用者
     _cmd :调用方法的编号,即方法名
     */
    //1. 定义一个函数(函数名随便写)
    // 无返回值,参数(id,SEL)
    void tangtang_eat(id self, SEL _cmd){
        
        NSLog(@"调用糖糖的eat方法 %@ %@",self,NSStringFromSelector(_cmd));
    }
    
    
    
    /**
     2.处理为实现的实例方法
     动态添加方法,首先实现这个resolveInstanceMethod方法
     resolveInstanceMethod调用的情况:当调用了一个没有实现的方法,就会调用resolveInstanceMethod这个方法
     <#sel#>:没有实现的方法
     */
    + (BOOL)resolveInstanceMethod:(SEL)sel{
        
        // 动态添加未实现的方法
        if (sel == @selector(eat)) {
            /**
             v : void
             @ : 对象
             : : SEL
             */
            class_addMethod(self, sel, (IMP)tangtang_eat, "v@:");
           
            // 处理完
            return YES;
        }
        
        
        return [super resolveInstanceMethod:sel];
    }
    @end
    
    #在viewController中
    - (void)viewDidLoad {
        [super viewDidLoad];
       
        Person *p = [[Person alloc]init];
        //performSelector:即为动态添加方法
        [p performSelector:@selector(eat)];
    }
    
    输出日志
    #如果你要实现带有参数的(自己找两者的不同)
    
    #Person.m文件中
    // C语言中所有对象类型用 id
    void tangtang_eat(id self, SEL _cmd, id prame1){
        
        NSLog(@"调用糖糖的eat方法 %@ %@ %@",self,NSStringFromSelector(_cmd),prame1);
    }
    
    + (BOOL)resolveInstanceMethod:(SEL)sel{
        
        // 动态添加未实现的方法
        if (sel == @selector(eat:)) {
            /**
             v : void
             @ : 对象
             : : SEL
             */
            class_addMethod(self, sel, (IMP)tangtang_eat, "v@:@");
           
            // 处理完
            return YES;
        }
    
        return [super resolveInstanceMethod:sel];
    }
    
    #ViewControllers中
     [p performSelector:@selector(eat:) withObject:@11];
    
    
    输出日志,注意最后的11数字

    添加方法完结,晚安,好梦

    相关文章

      网友评论

        本文标题:runtime - 动态添加方法

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