利用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(@"存储失败");
}