使用场景

  • 开发:

如果一个类方法非常多,加载类到内存的时候也比较耗费资源,可以给每个方法生成映射表,动态添加方法。就是方法先定义好,但是使用的时候才加载。

  • 面试:

有没有使用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
posted on 2018-10-08 16:35  广坤山货  阅读(236)  评论(0编辑  收藏  举报