runtime学习iOSios developers

runtime简单使用之动态添加方法

2016-03-08  本文已影响2803人  Alexander

一, runtime的动态添加方法功能

二, 步骤


在 WGStudent.h文件中
#import <Foundation/Foundation.h>

@interface WGStudent : NSObject

// 如果该方法只有声明没有实现,那么该方法一定不会放在方法列表中,外界一定不能直接调用到方法
  - (void)study;

@end
在ViewController.h文件中
#import "ViewController.h"
#import "WGStudent.h"
#import <objc/message.h>

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    WGStudent *student = [[WGStudent alloc] init];

    objc_msgSend(student, @selector(study));

}
@end
// 根本找不到这个方法
reason: '-[WGStudent study]: unrecognized selector sent to instance 0x7f94bb46e070'
// 动态去判断下eat方法有没有实现,如果没有实现,动态添加.
// 作用:处理未实现的对象方法
// 调用时刻:只要调用了一个不存在的对象方法就会调用
// sel:就是未实现方法编号

// 判断对象方法有没有实现
+(BOOL)resolveInstanceMethod:(SEL)sel

// 判断类方法有没有实现
+ (BOOL)resolveClassMethod:(SEL)sel

// dynamicMethodIMP方法
// 动态添加这个dynamicMethodIMP方法
void dynamicMethodIMP(id self, SEL _cmd) {
    // implementation ....
}

// 苹果内部的动态添加方法
@implementation MyClass
+ (BOOL)resolveInstanceMethod:(SEL)aSEL
{
    if (aSEL == @selector(resolveThisMethodDynamically)) {
          class_addMethod([self class], aSEL, (IMP) dynamicMethodIMP, "v@:");
          return YES;
    }
    return [super resolveInstanceMethod:aSEL];
}
@end
// 参数解释:
        // Class;给哪个类添加方法
        // SEL:添加方法
        // IMP:方法实现,函数名
        // types:方法类型(不要去死记,官方文档中有)
class_addMethod(__unsafe_unretained Class cls, SEL name, IMP imp, const char *types)
在WGStudent.m文件中
// 模仿官方文档来动态添加方法
#import "WGStudent.h"
#import <objc/message.h>

@implementation WGStudent

void studyEngilsh(id self, SEL _cmd) {

    NSLog(@"动态添加了一个学习英语的方法");
}

+ (BOOL)resolveInstanceMethod:(SEL)sel {

    if (sel == NSSelectorFromString(@"studyEngilsh")) {
        // 注意:这里需要强转成IMP类型
        class_addMethod(self, sel, (IMP)studyEngilsh, "v@:");
        return YES;
    }
    // 先恢复, 不然会覆盖系统的方法
    return [super resolveInstanceMethod:sel];
}
@end

在ViewController.m文件中
#import "ViewController.h"
#import "WGStudent.h"
#import <objc/message.h>

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    WGStudent *student = [[WGStudent alloc] init];

    [student performSelector:@selector(studyEngilsh)];
}
@end
// 说明动态添加方法成功
2016-03-08 20:07:23.160 sasass[1280:35172] 动态添加了一个学习英语的方法

总结 : 不懂就去模仿官方文档,里面很详细

上一篇 下一篇

猜你喜欢

热点阅读