iOS —— RunTime详解(动态添加方法)三

一、动态添加方法

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

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

+ (BOOL)resolveInstanceMethod:(SEL)sel:当对象调用了没有实现的方法没有实现就会调用resolveInstanceMethod。

resolveInstanceMethod作用:知道哪些方法没有实现,从而动态添加方法

sel:没有实现的方法

//动态添加的方法:

参数一:cls:给哪个类添加方法

参数二:SEL 添加方法的方法编号是什么

参数三:IMP:方法实现,函数入口,函数名

class_addMethod(Class _Nullable cls, SEL _Nonnull name, IMP _Nonnull imp,

                const char * _Nullable types)

Persion.m

#import "Persion.h"
#import <objc/message.h>
@implementation Persion


+(BOOL)resolveInstanceMethod:(SEL)sel
{
    //NSLog(@"%@",NSStringFromSelector(sel));
    //动态添加eat方法
    if (sel == @selector(eat))  {
        
        /*
         参数一:cls: 给哪个类添加方法
         参数二:SEL: 添加方法的方法编号是什么
         参数三:IMP:方法实现,函数入口,函数名
         参数四:types:方法类型
         
         */
        //动态添加方法
        class_addMethod(self, sel, (IMP)eat, "v@:");
        
        return YES;
        
    }
    //添加添加跑的方法
    else if (sel == @selector(run:))
    {
        class_addMethod(self, sel, (IMP)run, "v@:@");
        
        return YES;
        
    }
    
    return [super resolveInstanceMethod:sel];
}
#pragma mark- 下面的是C语言的函数
/*
 默认一个方法都有两个参数,self,_cmd,隐式参数
 self:方法调用者
 _cmd:调用方法的编号
 
 */

// 定义的函数
void eat(id self,SEL _cmd)
{
    NSLog(@"动态添加的方法1=%@ %@",self,NSStringFromSelector(_cmd));
}

//定义的函数run
void run(id self,SEL _cmd,id number)
{
    NSLog(@"动态添加跑步=%@",number);
    
}

Viewcontroller

#import "ViewController.h"
#import "Persion.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    Persion *p=[[Persion alloc]init];
    
    [p performSelector:@selector(eat)];
    
    //带参数
    [p performSelector:@selector(run:) withObject:@30];
    
    
}

猜你喜欢

转载自blog.csdn.net/u012189584/article/details/79543349