一、动态添加方法
开发使用场景:如果一个类方法非常多,加载类到内存的时候也比较耗费资源,需要给每个方法生成映射表,可以使用动态给某个类,添加方法解决。
经典面试试题:有没有使用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];
}