美文网首页
iOS runtime 使用场景

iOS runtime 使用场景

作者: jjslove | 来源:发表于2017-09-19 16:25 被阅读0次

    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中使用过这个。

    相关文章

      网友评论

          本文标题:iOS runtime 使用场景

          本文链接:https://www.haomeiwen.com/subject/kowwsxtx.html