美文网首页
利用Runtime 进行接档归档

利用Runtime 进行接档归档

作者: 努力奔跑的小男孩 | 来源:发表于2017-05-16 13:39 被阅读45次

    | 首先进行接档归档前, 存储数据需要遵循<NSCoding>协议 和引入 #import <objc/runtime.h> 头文件.然后具体代码如下:

    // 归档数据
    - (void)encodeWithCoder:(NSCoder *)aCoder {
             unsigned int count;
             Ivar *ivar = class_copyIvarList([self class], &count);
               for (int i=0; i < count; i++) {
                     Ivar iv = ivar[i];
                      // c字符串
                     const char *name = ivar_getName(iv);
                    // 属性的名称 --- key
                     NSString *strName = [NSString stringWithUTF8String:name];
                    //利用KVC取值
                    id value = [self valueForKey:strName];
                    [aCoder encodeObject:value forKey:strName];
             }
               free(ivar);
    }
    
    // 解档数据
    - (instancetype)initWithCoder:(NSCoder *)aDecoder {
        if (self = [super init])  {
            /*
             OBJC_EXPORT Ivar *class_copyIvarList(Class cls, unsigned int *outCount)
             Class cls 表示获取那一个类的属性列表
             unsigned int *outCount 用于存储获取到属性个数
             */
            unsigned int count = 0;
            Ivar *ivar = class_copyIvarList([self class], &count);
            for (int i = 0; i < count; i++) {
                //根据每一个属性取出对应的key 注意key值是c语言的key
                Ivar iva = ivar[i];
                // c 字符串
                const char *key = ivar_getName(iva);
                // 转换为oc
                NSString *strName = [NSString stringWithUTF8String:key];
                //进行解档取值
                id value = [aDecoder decodeObjectForKey:strName];
                //利用KVC对属性赋值
                [self setValue:value forKey:strName];
            }
            free(ivar);
        }
        return self;
    }
    

    Demo

    Person.h文件里面包含一个ChildModel(孩子模型) 和 一个PersonModel(父母模型)

    #import <Foundation/Foundation.h>
    
    
    @interface ChildModel : NSObject<NSCoding>
    @property(nonatomic, copy)NSString *name; // 孩子姓名
    @property(nonatomic, copy)NSString *age; // 孩子年龄
    @property(nonatomic, copy)NSString *schoolName; // 学校名
    @end
    
    
    @interface PersonModel : NSObject<NSCoding>
    @property(nonatomic, copy)NSString *name; // 父母姓名
    @property(nonatomic, copy)NSString *age; // 父母年龄
    @property(nonatomic, strong)NSArray <ChildModel *> *childs; // 孩子数组
    @end
    

    Person.m文件

    #import "PersonModel.h"
    #import <objc/runtime.h>
    
    @implementation ChildModel
    // 归档数据
    - (void)encodeWithCoder:(NSCoder *)aCoder {
        unsigned int count;
        Ivar *ivar = class_copyIvarList([self class], &count);
        for (int i=0; i < count; i++) {
            Ivar iv = ivar[i];
            // c字符串
            const char *name = ivar_getName(iv);
            // 属性的名称 --- key
            NSString *strName = [NSString stringWithUTF8String:name];
            //利用KVC取值
            id value = [self valueForKey:strName];
            [aCoder encodeObject:value forKey:strName];
        }
        free(ivar);
    }
    
    // 解档数据
    - (instancetype)initWithCoder:(NSCoder *)aDecoder {
        if (self = [super init])  {
            /*
             OBJC_EXPORT Ivar *class_copyIvarList(Class cls, unsigned int *outCount)
             Class cls 表示获取那一个类的属性列表
             unsigned int *outCount 用于存储获取到属性个数
             */
            unsigned int count = 0;
            Ivar *ivar = class_copyIvarList([self class], &count);
            for (int i = 0; i < count; i++) {
                //根据每一个属性取出对应的key 注意key值是c语言的key
                Ivar iva = ivar[i];
                // c 字符串
                const char *key = ivar_getName(iva);
                // 转换为oc
                NSString *strName = [NSString stringWithUTF8String:key];
                //进行解档取值
                id value = [aDecoder decodeObjectForKey:strName];
                //利用KVC对属性赋值
                [self setValue:value forKey:strName];
            }
            free(ivar);
        }
        return self;
    }
    @end
    
    @implementation PersonModel
    // 归档数据
    - (void)encodeWithCoder:(NSCoder *)aCoder {
        unsigned int count;
        Ivar *ivar = class_copyIvarList([self class], &count);
        for (int i=0; i < count; i++) {
            Ivar iv = ivar[i];
            // c字符串
            const char *name = ivar_getName(iv);
            // 属性的名称 --- key
            NSString *strName = [NSString stringWithUTF8String:name];
            //利用KVC取值
            id value = [self valueForKey:strName];
            [aCoder encodeObject:value forKey:strName];
        }
        free(ivar);
    }
    
    // 解档数据
    - (instancetype)initWithCoder:(NSCoder *)aDecoder {
        if (self = [super init])  {
            /*
             OBJC_EXPORT Ivar *class_copyIvarList(Class cls, unsigned int *outCount)
             Class cls 表示获取那一个类的属性列表
             unsigned int *outCount 用于存储获取到属性个数
             */
            unsigned int count = 0;
            Ivar *ivar = class_copyIvarList([self class], &count);
            for (int i = 0; i < count; i++) {
                //根据每一个属性取出对应的key 注意key值是c语言的key
                Ivar iva = ivar[i];
                // c 字符串
                const char *key = ivar_getName(iva);
                // 转换为oc
                NSString *strName = [NSString stringWithUTF8String:key];
                //进行解档取值
                id value = [aDecoder decodeObjectForKey:strName];
                //利用KVC对属性赋值
                [self setValue:value forKey:strName];
            }
            free(ivar);
        }
        return self;
    }
    @end
    

    存取

    NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
        NSString *temp = [NSString stringWithFormat:@"/%d.txt",90];
        NSString *fileName =  [path stringByAppendingPathComponent:temp];
        NSLog(@"fileName--%@\n",fileName);
        
        PersonModel *perModel = [[PersonModel alloc]init];
        perModel.name = @"王建";
        perModel.age = @"40";
        
        ChildModel *child1 = [[ChildModel alloc]init];
        child1.name = @"男孩";
        child1.age = @"23";
        child1.schoolName = @"上海复旦大学";
        ChildModel *child2 = [[ChildModel alloc]init];
        child2.name = @"女孩";
        child2.age = @"25";
        child2.schoolName = @"北京清华大学";
        
        perModel.childs = @[child1,child2];
        
        BOOL flag = [NSKeyedArchiver archiveRootObject:perModel toFile:fileName];
        if (flag) {
            NSLog(@"存储成功");
            //读取数据 
            PersonModel *permodel = [NSKeyedUnarchiver unarchiveObjectWithFile:fileName];
            NSLog(@"\n名字:%@\n年龄:%@\n",perModel.name,perModel.age);
            for (ChildModel *child in perModel.childs) {
                NSLog(@"孩子姓名%@年龄:%@学校:%@",child.name,child.age,child.schoolName);
            }
        }else{
            NSLog(@"存储失败");
        }
    
    打印结果
    打印结果.png

    相关文章

      网友评论

          本文标题:利用Runtime 进行接档归档

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