iOS runtime

2018-03-12  本文已影响5人  Jessica124

runtime概念

runtime在项目中应用

1、给分类(category)加属性

在分类中添加方法比较常用,看到有些文章说不能为分类添加属性,实际上是可以实现的,具体demo
可参考: https://www.jianshu.com/p/650bfdf12d11

2、黑魔法:method swizzling

Method Swizzling本质上就是对IMP和SEL进行交换。

//头文件需导入#import <objc/runtime.h>
- (void)hookMethod:(SEL)oldSEL newSEL:(SEL) newSEL {
    if (! oldSEL) {
        return;
    }
    if (! newSEL) {
        return;
    }
    Method oldMethod = class_getInstanceMethod([self class], oldSEL);
    assert(oldMethod);
    Method newMethod = class_getInstanceMethod([self class], newSEL);
    assert(newMethod);
    BOOL addSuccess = class_addMethod([self class], newSEL, newMethod, nil);
    if (addSuccess) {
        method_exchangeImplementations(oldMethod, newMethod);
    }
}
3、动态添加方法
- (void)viewDidLoad {
    [super viewDidLoad];   
    Person *p = [[Person alloc] init];
    // 默认person,没有实现run:方法,可以通过performSelector调用,但是会报错。
    // 动态添加方法就不会报错
    [p performSelector:@selector(run:) withObject:@10];
}

@implementation Person
// 没有返回值,1个参数
// void,(id,SEL)
void aaa(id self, SEL _cmd, NSNumber *meter) {
    NSLog(@"跑了%@米", meter);
}

// 任何方法默认都有两个隐式参数,self,_cmd(当前方法的方法编号)
// 什么时候调用:只要一个对象调用了一个未实现的方法就会调用这个方法,进行处理
// 作用:动态添加方法,处理未实现
+ (BOOL)resolveInstanceMethod:(SEL)sel
{
    // [NSStringFromSelector(sel) isEqualToString:@"run"];
    if (sel == NSSelectorFromString(@"run:")) {
        // 动态添加run方法
        // class: 给哪个类添加方法
        // SEL: 添加哪个方法,即添加方法的方法编号
        // IMP: 方法实现 => 函数 => 函数入口 => 函数名(添加方法的函数实现(函数地址))
        // type: 方法类型,(返回值+参数类型) v:void @:对象->self :表示SEL->_cmd
        class_addMethod(self, sel, (IMP)aaa, "v@:@");
        return YES;
    }
    return [super resolveInstanceMethod:sel];
}
@end

// 打印输出
2016-02-17 19:05:03.917 runtime[12761:543574] runtime动态添加方法--跑了10米
4、字典转模型MJKeyValue
上一篇 下一篇

猜你喜欢

热点阅读