使用场景
- 开发:
如果一个类方法非常多,加载类到内存的时候也比较耗费资源,可以给每个方法生成映射表,动态添加方法。就是方法先定义好,但是使用的时候才加载。
- 面试:
有没有使用performSelector,其实主要想问有没有动态添加过方法。
实现原理
当使用performSelector调用某个没有实现的实例方法或者类方法时,会调用这个对象的+ (BOOL)resolveInstanceMethod:(SEL)sel
或者+ (BOOL)resolveClassMethod:(SEL)sel
,然后可以根据参数sel(参数sel就是没有实现的方法)来做一系列的操作。
实现步骤
1.创建Dog类,继承于NSObject,并添加头文件import <objc/runtime.h>
.
2.实现对应的+ (BOOL)resolveInstanceMethod:(SEL)sel
或者+ (BOOL)resolveClassMethod:(SEL)sel
方法
/**
* 当调用了没有实现的方法没有实现就会调用
* @param sel 没有实现的方法
* @return 如果方法被发现并添加return:YES 否则NO
*/
+ (BOOL)resolveInstanceMethod:(SEL)sel{
if (sel == NSSelectorFromString(@"run:")) {
BOOL isSuccess = class_addMethod(self, sel, (IMP)run, "v@:@");
return isSuccess;
}
return [super resolveInstanceMethod:sel];
}
/**
* 任何方法默认都有两个隐式参数,self,_cmd(_cmd代表方法编号,打印结果为当前执行的方法名)
* 什么时候调用:只要一个对象调用了一个未实现的方法就会调用这个方法,进行处理
* 作用:动态添加方法,处理未实现
*/
void run(id self,SEL _cmd,NSString *param){
NSLog(@"self = %@,method = %@,param = %@",self,NSStringFromSelector(_cmd),param);
}
3.使用performSelector调用run:方法
Dog *dog = [[Dog alloc] init];
[dog performSelector:@selector(run:) withObject:@"The dog is running"];
4.运行
self = <Dog: 0x604000009980>,method = run:,param = The dog is running