iOS runtime 使用场景

2017-09-19  本文已影响0人  jjslove

runtime的功能很强大,包含的的内容也很多,见下图



但是我们平时项目中使用的并不是很多,以下是几种常见的场景:

1. 字典转换为模型。

通过网络接口获取的数据一般是 JSON 格式的,需要转为我们自定义的模型,方便使用。
定义BaseModel,所有模型的基类。
BaseModel.h

#import <Foundation/Foundation.h>

@interface BaseModel : NSObject

-(id)initWithDic:(NSDictionary *)dic;

@end

BaseModel.m


#import "BaseModel.h"
#import <objc/runtime.h>

@implementation BaseModel

-(id)initWithDic:(NSDictionary *)dic{
    //Class cls = [self class];
    unsigned int count = 0;
    objc_property_t *properties = class_copyPropertyList([self class], &count);
    for (int i=0; i<count; i++) {
        objc_property_t property = properties[i];
        NSString *propertyName = [[NSString alloc] initWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
        id value = [dic objectForKey:propertyName];
        if (!value) {
            continue;
        }
        [self setValue:value forKey:propertyName];
        
    }
    free(properties);
    return  self;
}


@end

定义数据模型Model
Model.h

#import "BaseModel.h"

@interface Model : BaseModel

@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *sex;
@property (nonatomic, strong) NSNumber *age;

@end

Model.m

#import "Model.h"

@implementation Model

@end

声明Model的实例并使用

NSDictionary *dic = @{@"name": @"Brook",
                              @"sex": @"male",
                              @"age": @(10)};
        
Model *model = [[Model alloc] initWithDic:dic];
NSLog(@"model name=%@", model.name);
2.Method Swizzling

在没有一个类的实现源码的情况下,想改变其中一个方法的实现,除了继承它重写、和借助类别重名方法暴力抢先之外,还有一个方法就是Method Swizzling.
Person.m

#import "Person.h"
#import <objc/runtime.h>
@implementation Person

-(NSString *)run{
    return @"run";
}

-(NSString *)study{
    return @"study";
}

@end

Person.h

#import "Animal.h"

@interface Person : Animal

-(NSString *)run;
-(NSString *)study;

@end

上面是一般情况,调用结果如下:

image.png

添加Method Swizzling魔法,修改Person.m代码

#import "Person.h"
#import <objc/runtime.h>
@implementation Person

+(void)load1{
    Method methodRun = class_getInstanceMethod([self class], @selector(run));
    Method methodStudy = class_getInstanceMethod([self class], @selector(study));
    method_exchangeImplementations(methodRun, methodStudy);
}

-(NSString *)run{
    return @"run";
}

-(NSString *)study{
    return @"study";
}

@end

添加魔法后的调用结果:


image.png

两个方法进行了调用,著名下拉刷新第三方软件MJRefresh中使用过这个。

上一篇下一篇

猜你喜欢

热点阅读