利用Runtime 进行接档归档

2017-05-16  本文已影响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
上一篇下一篇

猜你喜欢

热点阅读