iOS开发过程中一些数据的存储归档

iOS开发难免会有数据的存储,对于一些常规的对象即简单地对象,文件读写只支持NSString,NSarray ,NDictionary,NSdata,既简单对象的数据持久化那么对于一些自定义的复杂类对象我们就需要进行数据的归档存储,一般我们对于一些比较复杂的数据对象的归档大致分为下列几个步骤:
1. 复杂对象写入文件,必须先转化成为NSData
2. 复杂对象只能通过归档(序列化,编码)转化为NSData
3. 对复杂对象实现归档的要求:

  • 复杂对象需要遵守协议
  • 复杂对象的属性,实例变量,如果是对象类型,也必须遵守协议

eg:列举一个归档的例子,如果针对一个Person对象进行归档代码如下:

Person.h文件如下
@interface Person : NSObject<NSCoding>
@property(nonatomic,retain)NSString * name;
@property(nonatomic,assign)NSInteger age;
@property(nonatomic,retain)NSString * gender;
@end
Person.m文件如下
@implementation Person
//对Person对象进行编码时候,此方法执行。
//对person中要想进行归档的所有属性,进行编码操作
- (void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:self.name forKey:@"name"];
    [aCoder encodeObject:self.gender forKey:@"gender"];
//    [aCoder encodeInteger:self.age forKey:@"age"];
}
//对person对象进行反归档时候,执行该方法
//创建一个新的person对象,所有属性都是解码得到的
- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [self init];
    if (self) {
        self.name = [aDecoder decodeObjectForKey:@"name"];
        self.gender = [aDecoder decodeObjectForKey:@"gender"];
        self.age = [aDecoder decodeIntegerForKey:@"age"];
    }
    return self;   
}
@end
在viewController中使用对象进行归档代码如下:
对象的归档
//对复杂的对象进行归档person=》NSData
    Person * p = [[Person alloc] init];
    p.name = @"kevin";
    p.gender = @"male";
    p.age = 25;
    NSMutableData * data = [NSMutableData dataWithCapacity:40];
    //创建归档工具对象
    NSKeyedArchiver * archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];

    [archiver encodeObject:p forKey:@"person"];//归档 这里面调用的就是nscoding的两个协议方法
    [archiver finishEncoding];//归档结束
    //将归档后的NSData,写入文件,存储在沙盒中
    NSString * documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];
    NSString * filePath = [documentPath stringByAppendingPathComponent:@"savePerson"];
    [data writeToFile:filePath atomically:YES];
对象的解档
//根据文件路径读取data
    NSString * documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];
    NSString * filePath = [documentPath stringByAppendingPathComponent:@"savePerson"];

    NSData * data = [NSData dataWithContentsOfFile:filePath];
    //将Nsdata 通过反归档,转化成person对象
    NSKeyedUnarchiver * unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
    //通过方归档得到复杂对象
    Person * p = [unarchiver decodeObjectForKey:@"person"];
    [unarchiver finishDecoding];
    NSLog(@"name = %@",p.name);
    NSLog(@"gender = %@",p.gender);
    NSLog(@"age = %d",p.age);

看似一切都感觉还可以吧,挺顺利的。但是假如你这个复杂对象的属性有一两百个,是不是会感觉到整个人都不好呢,分析下,这种归档和解档明显是通过Object-c中KVC进行的存取,经过查阅资料可以使用objc/runtime+KVC实现

思路如下:
1. 动态获取这个类中所有的属性
2. 然后根据获取的属性字符利用KVC进行归档

废话少说上干活

#import<objc/runtime.h>

Ivar *varA = class_copyIvarList([Person class],&count);
for(int i = 0:i < count:i ++){
    Ivar v = varA[i];
    const char *name = ivar_getName(v);
    NSLog(@"%s",name);
    //你会看到它会将这个类中多有的属性以字符形式输入
}

KVC取值

id value = [self valueForKey:strName];
[encoder encodeObject:value forKey:strName];

在Person类的.m文件实现如下代码

归档如下
//归档
- (void)encodeWithCoder:(NSCoder *)encoder
{
    unsigned int count;
    Ivar *ivar = class_copyIvarList([Person class], &count);
    for (int i=0; i<count; i++) {
        Ivar iv = ivar[i];
        const char *name = ivar_getName(iv);
        NSString *strName = [NSString stringWithUTF8String:name];
        //利用KVC取值
        id value = [self valueForKey:strName];
        [encoder encodeObject:value forKey:strName];
    }
    free(ivar);
}
@end
解档如下
//解档
- (id)initWithCoder:(NSCoder *)decoder
{
    if (self = [super init]) {
        unsigned int count = 0;
        //获取类中所有成员变量名
        Ivar *ivar = class_copyIvarList([Person class], &count);
        for (int i = 0; i<count; i++) {
            Ivar iva = ivar[i];
            const char *name = ivar_getName(iva);
            NSString *strName = [NSString stringWithUTF8String:name];
            //进行解档取值
            id value = [decoder decodeObjectForKey:strName];
            //利用KVC对属性赋值
            [self setValue:value forKey:strName];
        }
        free(ivar);
    }
    return self;
}

是不是瞬间感觉整个人好多了。O(∩_∩)O哈哈~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值