博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Runtime应用(三)实现NSCoding的自动归档和自动解档
阅读量:6325 次
发布时间:2019-06-22

本文共 2575 字,大约阅读时间需要 8 分钟。

当我们需要将一个对象进行归档时,都要让该对象的类遵守NSCoding协议,再实现归档和接档方法。例如有一个Person类,该类有两个成员变量

@property (nonatomic,copy) NSString *name;@property (nonatomic,assign) int age;

两个协议的实现方法如下

/** *  将对象写入某个文件时需要调用,在该方法中说明哪些属性需要存储 */- (void)encodeWithCoder:(NSCoder *)encoder{    [encoder encodeObject:self.name forKey:@"name"];    [encoder encodeInt:self.age forKey:@"age"];}/** *  从文件中解析对象时会调用,在该方法中解析对象的属性 */- (id)initWithCoder:(NSCoder *)decoder{    if (self = [super init]) {        // 解析之后要赋值给属性        _name = [decoder decodeObjectForKey:@"name"];        _age = [decoder decodeIntForKey:@"age"];    }    return self;}

但当该类拥有上百个属性时,那将会花费更多的功夫在重复代码上,所以使用运行时机制截取类的成员变量,进行赋值

 

例如有一个狗类Dog和它的父类动物类Animal

狗类的成员变量有

@property (nonatomic,copy) NSString *name;@property (nonatomic,assign) int age;

 

动物类的成员变量有

@property (nonatomic,assign) double weight;

 

当我们需要将狗对象进行归档时,可以在类中这样重写归档和解档方法

- (id)initWithCoder:(NSCoder *)aDecoder{       if (self = [super init]) {        Class c = self.class;        // 截取类和父类的成员变量        while (c && c != [NSObject class]) {            unsigned int count = 0;            Ivar *ivars = class_copyIvarList(c, &count);            for (int i = 0; i < count; i++) {                               NSString *key = [NSString stringWithUTF8String:ivar_getName(ivars[i])];                               id value = [aDecoder decodeObjectForKey:key];                               [self setValue:value forKey:key];            }            // 获得c的父类            c = [c superclass];            free(ivar);        }                  }    return self;}- (void)encodeWithCoder:(NSCoder *)aCoder{        Class c = self.class;    // 截取类和父类的成员变量    while (c && c != [NSObject class]) {        unsigned int count = 0;               Ivar *ivars = class_copyIvarList(c, &count);               for (int i = 0; i < count; i++) {            Ivar ivar = ivars[i];            NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)];            id value = [self valueForKey:key];                       [aCoder encodeObject:value forKey:key];        }        c = [c superclass];        // 释放内存        free(ivar);    }   }

 

 代码测试:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{    CXDog *d = [[CXDogalloc] init];    d.name = @"cx";    d.age = 12;    d.weight = 1.55;    // 将对象归档    [NSKeyedArchiverarchiveRootObject:d toFile:@"/Users/c_xie/Desktop/wj.xxoo"];    // 将对象解档    CXDog *dog = [NSKeyedUnarchiverunarchiveObjectWithFile:@"/Users/c_xie/Desktop/wj.xxoo"];    NSLog(@"%@,%d,%f",dog.name,dog.age,d.weight);   }

以后就算有再多的属性,一个循环搞定

 

转载于:https://www.cnblogs.com/junhuawang/p/5798827.html

你可能感兴趣的文章
码栈开发手册(五)---可视化方式开发(模块详解--流程)
查看>>
myrocks记录格式分析
查看>>
PostgreSQL、Greenplum DML合并操作 最佳实践
查看>>
阿里云人工智能科学家闵万里犀利点评:现在的人工智能有点过热
查看>>
Spark修炼之道(高级篇)——Spark源码阅读:第十节 Standalone运行模式解析
查看>>
移动应用要如何埋点上传才能收集更多数据?
查看>>
MIDle生命周期详解,以及工作原理
查看>>
Nginx + Shiro + Ehcache 实现负载均衡集群(成绩报告查询系统)
查看>>
Java CRC32的用法
查看>>
Google官方网络框架Volley实战——QQ吉凶测试,南无阿弥陀佛!
查看>>
【 MAKEFILE 编程基础之一】详细介绍MAKEFILE概念和其机制用途;
查看>>
C#几个经常犯错误汇总
查看>>
Java 三大特性之继承
查看>>
虚拟机10:使用U盘及U盘启动
查看>>
MySQl的几个配置项
查看>>
linux命令学习——tar
查看>>
UIWebView清除缓存和cookie[转]
查看>>
PHP静态调用非静态方法
查看>>
Spring AOP 实现之CGLIB
查看>>
【原创】erlang 模块之 pg2
查看>>