美文网首页
RunTime运行时之动态添加方法

RunTime运行时之动态添加方法

作者: 飘金 | 来源:发表于2017-06-07 12:30 被阅读0次
#import "ViewController.h"
#import "Person.h"
/* 
    1:
    Runtime(动态添加方法):OC都是懒加载机制,只要一个方法实现了,就会马上添加到方法列表中.
    app:免费版,收费版
    QQ,微博,直播等等应用,都有会员机制
    performSelector:去执行某个方法。performSelector withObject :object为前面方法的参数
    
    2:
    美团有个面试题?有没有使用过performSelector,什么时候使用?动态添加方法的时候使用过?怎么动态添加方法?用runtime?为什么要动态添加方法?
 */

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
//    _cmd:当前方法的方法编号
    
    Person *p = [[Person alloc] init];
    
    // 执行某个方法
//    [p performSelector:@selector(eat)];
    
    [p performSelector:@selector(run:) withObject:@10];
    

}

@end

#import "Person.h"
#import <objc/message.h>

@implementation Person

// 没有返回值,也没有参数
// void,(id,SEL)
void aaa(id self, SEL _cmd, NSNumber *meter) {
    
    NSLog(@"跑了%@", meter);
    
}

任何方法默认都有两个隐式参数,self,_cmd(_cmd代表方法编号,打印结果为当前执行的方法名)

什么时候调用:只要一个对象调用了一个未实现的方法就会调用这个方法,进行处理

作用:动态添加方法,处理未实现

+ (BOOL)resolveInstanceMethod:(SEL)sel
{
    // [NSStringFromSelector(sel) isEqualToString:@"eat"];
    if (sel == NSSelectorFromString(@"run:")) {
        // eat
        // class: 给哪个类添加方法
        // SEL: 添加哪个方法
        // IMP: 方法实现 => 函数 => 函数入口 => 函数名
        // type: 方法类型:void用v来表示,id参数用@来表示,SEL用:来表示
        //aaa不会生成方法列表
        class_addMethod(self, sel, (IMP)aaa, "v@:@");
        
        return YES;
    }
    
    return [super resolveInstanceMethod:sel];

}

//- (void)test
//{
//    // [NSStringFromSelector(sel) isEqualToString:@"eat"];
//    if (sel == NSSelectorFromString(@"eat")) {
//        // eat
//        // class: 给哪个类添加方法
//        // SEL: 添加哪个方法
//        // IMP: 方法实现 => 函数 => 函数入口 => 函数名
//        // type: 方法类型
//        class_addMethod(self, sel, (IMP)aaa, "v@:");
//        
//        return YES;
//    }
//    
//    return [super resolveInstanceMethod:sel];
//}
@end

3.动态添加方法

  • 开发使用场景:如果一个类方法非常多,加载类到内存的时候也比较耗费资源,需要给每个方法生成映射表,可以使用动态给某个类,添加方法解决。

  • 经典面试题:有没有使用performSelector,其实主要想问你有没有动态添加过方法。

  • 简单使用

@implementation ViewController

 

- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view, typically from a nib.

    

    Person *p = [[Person alloc] init];

    

    // 默认person,没有实现eat方法,可以通过performSelector调用,但是会报错。

    // 动态添加方法就不会报错

    [p performSelector:@selector(eat)];

}
@end

@implementation Person

// void(*)()

// 默认方法都有两个隐式参数,

void eat(id self,SEL sel)

{

    NSLog(@"%@ %@",self,NSStringFromSelector(sel));

}

当一个对象调用未实现的方法,会调用这个方法处理,并且会把对应的方法列表传过来.

刚好可以用来判断,未实现的方法是不是我们想要动态添加的方法

+ (BOOL)resolveInstanceMethod:(SEL)sel

{
    if (sel == @selector(eat)) {

        // 动态添加eat方法
        // 第一个参数:给哪个类添加方法

        // 第二个参数:添加方法的方法编号

        // 第三个参数:添加方法的函数实现(函数地址)

        // 第四个参数:函数的类型,(返回值+参数类型) v:void @:对象->self :表示SEL->_cmd

        class_addMethod(self, @selector(eat), eat, "v@:");
        return YES;

    }
    return [super resolveInstanceMethod:sel];

}

@end

相关文章

  • IOSRunTime_动态添加方法

    利用RunTime运行时,动态添加一个方法 动态添加方法,首先实现这个resolveInstanceMethod ...

  • runTime之--动态添加方法

    Runtime运行时之--动态添加方法 - OC都是懒加载机制、只要方法实现了,就会马上添加到方法列表List中-...

  • iOS 之runtime消息传递和转发

    runtime 运行时,oc是一门动态性语言,程序在运行时可改变结构,如添加方法,交换方法等.其实runtime就...

  • runtime常见问题

    1 . iOS runtime 运行时,动态添加属性方法首先, 要明白为什么要动态给类添加方法? 如果一个类方法很...

  • runtime的理解(二)

    主要内容 利用 runtime 交换方法 利用 runtime 动态添加方法 利用 runtime 动态添加属性 ...

  • runtime

    runtime交换方法 动态添加方法

  • RunTime运行时之动态添加方法

    任何方法默认都有两个隐式参数,self,_cmd(_cmd代表方法编号,打印结果为当前执行的方法名) 什么时候调用...

  • 为什么说OC是一门动态语言?

    自己理解:OC语言是在运行时才确定类型的,通过Runtime运行时机制,在运行时动态的添加变量,方法,类等,所以说...

  • 自己实现OC的KVO

    Runtime系列文章在这:Runtime介绍---术语介绍Runtime应用--动态添加方法Runtime应用-...

  • runtime和oc内存区域(2018-04-02)

    runtime常用的几个方法: 交换方法 动态添加属性 动态添加方法 1.交换方法 class_getClassM...

网友评论

      本文标题:RunTime运行时之动态添加方法

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