[Runtime]-动态添加方法

 有没有使用过performSelector,
 使用过
 
 何时使用?
 动态添加方法的时候使用过
 
 怎么动态添加方法?
 使用runtime
 
 为何要动态添加方法?
 OC都是懒加载机制,只要一个方法实现了,就会立刻添加到方法列表上.方法中有不少映射关系,这无形中就会消耗了内存
 好比一个app:有免费版、收费版
 好比:QQ、微博、直播等等应用,都有会员机制,这样咱们能够动态添加方法1ios

Runtime (动态添加方法):xcode

若是咱们建立一个Person类,而后在viewDidLoad中建立该对象,咱们使用performSelector去调用一个Person类中没有的方法,结果系统报错找不到方法:app

  • Person *p = [[Person alloc]init];
        // 执行某个方法
        [p performSelector:@selector(eat)];
  • #import <Foundation/Foundation.h>
    
    @interface Person : NSObject
    
    @end
    
    
    #import "Person.h"
    #import <objc/message.h>
    
    @implementation Person
    
    @end

这时候咱们能够动态去添加方法:ide

  1. 首先:咱们在Person 类中去实现一个方法:
  • // 任何方法默认都有两个隐式参数,self,_cmd
    // 做用:动态添加方法、或者处理一些未实现的方法
    // 何时调用?只要一个对象调用了一个未实现的方法,就会调用这个方法来进行处理
    + (BOOL)resolveInstanceMethod:(SEL)sel {
        
        //NSLog(@"%@",NSStringFromSelector(sel));
        //[NSStringFromSelector(sel) isEqualToString:@"eat"]
        
        if (sel == NSSelectorFromString(@"eat")) {
            // class:第一个参数:给那个类添加方法
            // SEL:添加哪一个方法
            // IMP:implementation:方法=>函数=>函数的入口=>函数名
            // type:方法的类型
            class_addMethod(self, sel, (IMP)funcA, "v@:");
            
            return YES;
        }
        
        return [super resolveInstanceMethod:sel];
    }

      2.主要是这个方法的参数咱们要掌握:class_addMethod(self, sel, (IMP)funcA, "v@:");函数

查看参数文档地址:xcode-->window-->Documentation and API Reference-->展开ios9.3-->Languages &     Utilities-->Objective-C-->Guides-->Objective-C Runtime Programming Guide-->Dynamic Method Resolution + Type Encodingsui

 Runtime中文文档地址连接: http://blog.csdn.net/liangliang103377/article/details/39007683    spa

  • // 声明一个函数
    void funcA(id self,SEL _cmd) {
        NSLog(@"吃东西");
    }
  • 最后打印:吃东西











若是咱们是动态建立一个带有参数的方法.net

  • #import "Person.h"
    #import <objc/message.h>
    
    @implementation Person
    
    // 声明一个函数
    void funcA(id self,SEL _cmd,NSNumber *metre) {
        NSLog(@"跑了%@米",metre);
    }
    
    + (BOOL)resolveInstanceMethod:(SEL)sel {
        
        //NSLog(@"%@",NSStringFromSelector(sel));
        
        //[NSStringFromSelector(sel) isEqualToString:@"eat"]
        if (sel == NSSelectorFromString(@"run:")) {
            // class:第一个参数:给那个类添加方法
            // SEL:添加哪一个方法
            // IMP:implementation:方法=>函数=>函数的入口=>函数名
            // type:方法的类型
            class_addMethod(self, sel, (IMP)funcA, "v@:@");
            
            return YES;
        }
        
        return [super resolveInstanceMethod:sel];
    }
    
    @end

方法的调用:code

  • - (void)viewDidLoad {
        [super viewDidLoad];
        
        // _cmd:当前方法方法编号
        NSLog(@"%@",NSStringFromSelector(_cmd));
        
        Person *p = [[Person alloc]init];
        // 执行某个方法
        [p performSelector:@selector(run:) withObject:@100];
        
    }

最后打印:跑了100米orm

 

知识点

  1. 1:任何方法默认都有两个隐式参数:self、_cmd
  1. 2:_cmd:当前方法方法编号
  2. 在ViewDidLoad中打印该参数:
  3. NSLog(@"%@",NSStringFromSelector(_cmd));

  3:+ (BOOL)resolveInstanceMethod:(SEL)sel  ?做用?何时调用?

    >何时调用?只要一个对象调用了一个未实现的方法,就会调用这个方法来进行处理
    >做用?动态添加方法、或者处理一些未实现的方法

  

意见反馈邮件:1415429879@qq.com 欢迎大家的阅读和赞扬、谢谢!

相关文章
相关标签/搜索