美文网首页
runtime 实现字典转模型,方法交换

runtime 实现字典转模型,方法交换

作者: 书上说says | 来源:发表于2019-05-05 15:27 被阅读0次

    先上一张图,了解一下,runtime对于我们开发而言可以用到哪些地方(借用网络大神的)


    173709-2be9edadc94d5cbb.png

    1.先了解一下,运用runtime实现访问对象的成员变量,这里以一个字典转模型说明:
    person.h 文件,声明了若干个成员变量

    #import <Foundation/Foundation.h>
    
    @interface Person : NSObject
    @property (assign,nonatomic) int ID;
    @property (assign,nonatomic) int weight;
    @property (assign,nonatomic) int age;
    @property (copy,nonatomic) NSString *name;
    @property (assign,nonatomic) int gradeID;
    - (void)eat;
    - (void)run;
    @end
    

    NSObject+JSON.m 文件
    (1)ivar_getTypeEncoding(ivar) 获取成员变量类型
    (2)ivar_getName(ivar) 获取成员变量名

    #import "NSObject+JSON.h"
    #import <objc/runtime.h>
    
    @implementation NSObject (JSON)
    + (instancetype)objectWithJson:(NSDictionary *)json {
        id obj = [[self alloc]init];
        
        unsigned int count;
        Ivar *ivars = class_copyIvarList(self, &count);
        
        for (int i=0; i<count; i++) {
            // 取出成员变量
            
            Ivar ivar = ivars[I];
            
            NSMutableString *type = [NSMutableString stringWithUTF8String:ivar_getTypeEncoding(ivar)];
            NSMutableString *name = [NSMutableString stringWithUTF8String:ivar_getName(ivar)];
            NSLog(@"type=%@,name=%@",type,name);
            [name deleteCharactersInRange:NSMakeRange(0, 1)];
            
            // 设值
            
            id value = json[name];
            if (value) {
                if ([name isEqualToString:@"ID"]) {
                    value  = json[@"id"];
                }
                [obj setValue:value forKey:name];
            }else {
                // 这里是做了特殊处理,设置了默认值,正常是不需要的
                if ([type isEqualToString:@"i"]) {
                    [obj setValue:@0 forKey:name];// int 类型,默认值
                } else {
                    [obj setValue:@"" forKey:name]; // NSString 类型,默认值
                }
            }
        }
        free(ivars);
        return obj;
    }
    @end
    
    // 字典转模型
    - (void)jsonToModel {
        NSDictionary *json = @{
                               @"id":@20,
                               @"age":@20,
    //                           @"weight":@60,
                               @"name":@"jack",
                               @"num":@123
                               };
        Person *person = [Person objectWithJson:json];
        
        NSLog(@"%@",person);
        NSLog(@"id = %d, age = %d, weight = %d, name = %@",person.ID,person.age,person.weight,person.name);
    }
    

    如果字典中没有给出对应的成员变量,则使用的默认值处理方法


    image.png

    2.还有一个关于runtime,实现方法交换的例子,在person.h里有eat(),run()方法,如果要实现两个方法的交换,两种方法:
    方法一:

        class_replaceMethod([Person class], @selector(run), imp_implementationWithBlock(^{
            NSLog(@"我是替换的方法");
        }), "V");
    
    image.png

    方法二:

        Method run = class_getInstanceMethod([Person class], @selector(run));
        Method eat = class_getInstanceMethod([Person class], @selector(eat));
        method_exchangeImplementations(run, eat);
    
    image.png

    如果需要交换外部方法,还可以有方法三:

    // 替换的方法
    void myRun() {
        NSLog(@"---myRun---");
    }
    
    - (void)exchangeMethod {
        Person *person = [[Person alloc]init];
        
        //方法一:
    //    class_replaceMethod([Person class], @selector(run), imp_implementationWithBlock(^{
    //        NSLog(@"我是替换的方法");
    //    }), "V");
        
        
        //方法二:
    //    Method run = class_getInstanceMethod([Person class], @selector(run));
    //    Method eat = class_getInstanceMethod([Person class], @selector(eat));
    //    method_exchangeImplementations(run, eat);
        
        //方法三:
        class_replaceMethod([Person class], @selector(run), (IMP)myRun, "V");
        
        [person run];
    
    }
    
    image.png

    相关文章

      网友评论

          本文标题:runtime 实现字典转模型,方法交换

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