数据归档与恢复 NSKeyedArchiver

归档与恢复归档

归档,英文Archiver[‘ɑrkɪvə],这里指的是将OC的对象存储为一个文件或者网络上的一个数据块。 
恢复归档,英文UnArchiver,指的是将一个来自文件或网络的归档数据块恢复成内存中的一个OC对象。 
归档和恢复主要用于对自定义类型对象进行存储,在程序暂停或关闭前保存自定义数据,在程序重新恢复状态或启动后读取存储的自定义数据。 
支持归档和恢复的类必须实现NSCoding协议,再由NSKeyedArchiver和NSKeyedUnarchiver类进行转换,将对象转换为数据流 
其它语言,如java/.net 将此技术称为序列化。

归档集合类型

IOS 很多内置类型都默认实现了归档功能,如NSNumber,NSArray,NSDictionary,NSString,NSData等。
定义NSArray或NSDicitionary类型,初始化数据后,调用NSKeyedArchiver 类的archiveRootObject 传入file路径,即可将当前NSArray对象完好的保存到文件系统中。 读取归档数据,使用NSKeydUnarchiver类unarchiveObjectWithFile方法可以直接从文件读回数据,并返回NSArray对象 NSKeyedArchiver和NSKeyedUnarchiver类都是将对象属性和值以key|value的方式顺序存储和读取的。 

 

很多时候我们需要归档和恢复自定义对象,因此需要让自定义对象实现归档功能 
实现归档只需要遵循(实现)NSCoding协议或是NSCoding的子协议。

NSKeyedArchiver

如果对象是NSString、NSDictionary、NSArray、NSData、NSNumber等类型,可以直接用NSKeyedArchiver进行归档和恢复 
不是所有的对象都可以直接用这种方法进行归档,只有遵守了NSCoding协议的对象才可以 
NSCoding协议有2个方法: 
encodeWithCoder: 
每次归档对象时,都会调用这个方法。一般在这个方法里面指定如何归档对象中的每个实例变量,可以使用encodeObject:forKey:方法归档实例变量 
initWithCoder: 
每次从文件中恢复(解码)对象时,都会调用这个方法。一般在这个方法里面指定如何解码文件中的数据为对象的实例变量,可以使用decodeObject:forKey方法解码实例变量

有时需要将多个对象归档到一个文件,此时我们需要使用NSMutableData作为缓冲存储对象。 
先将对象归档到NSData中,再将NSData写入到文件中。

NSKeyedArchiver-归档NSArray

归档一个NSArray对象到Documents/array.archive
NSArray *array = [NSArray arrayWithObjects:@”a”,@”b”,nil]; [NSKeyedArchiver archiveRootObject:array toFile:path]; 

 

恢复(解码)NSArray对象
NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithFile:path]

 

NSKeyedArchiver-归档Person对象(Person.h)

@interface Person : NSObject<NSCoding> @property (nonatomic, copy) NSString *name; @property (nonatomic, assign) int age; @property (nonatomic, assign) float height; @end 

 

NSKeyedArchiver-归档Person对象(Person.m)

@implementation Person
- (void)encodeWithCoder:(NSCoder *)encoder {
    [encoder encodeObject:self.name forKey:@"name"]; [encoder encodeInt:self.age forKey:@"age"]; [encoder encodeFloat:self.height forKey:@"height"]; } - (id)initWithCoder:(NSCoder *)decoder { self.name = [decoder decodeObjectForKey:@"name"]; self.age = [decoder decodeIntForKey:@"age"]; self.height = [decoder decodeFloatForKey:@"height"]; return self; } - (void)dealloc { [super dealloc]; [_name release]; } @end 

 

NSKeyedArchiver-归档Person对象(编码和解码)

//归档(编码)
Person *person = [[[Person alloc] init] autorelease];
person.name = @"wangzhaolu";
person.age = 26; person.height = 1.78f; [NSKeyedArchiver archiveRootObject:person toFile:path]; //恢复(解码) Person *person = [NSKeyedUnarchiver unarchiveObjectWithFile:path]; 

 

NSKeyedArchiver-归档对象的注意

如果父类也遵守了NSCoding协议,请注意:
应该在encodeWithCoder:方法中加上一句
[super encodeWithCode:encode];
确保继承的实例变量也能被编码,即也能被归档
应该在initWithCoder:方法中加上一句 self = [super initWithCoder:decoder]; 确保继承的实例变量也能被解码,即也能被恢复 

 

NSData

使用archiveRootObject:toFile:方法可以将一个对象直接写入到一个文件中,但有时候可能想将多个对象写入到同一个文件中,那么就要使用NSData来进行归档对象 
NSData可以为一些数据提供临时存储空间,以便随后写入文件,或者存放从磁盘读取的文件内容。可以使用[NSMutableData data]创建可变数据空间 
这里写图片描述

NSData-归档2个Person对象到同一文件中

//归档(编码)
// 新建一块可变数据区
NSMutableData *data = [NSMutableData data]; // 将数据区连接到一个NSKeyedArchiver对象 NSKeyedArchiver *archiver = [[[NSKeyedArchiver alloc] initForWritingWithMutableData:data] autorelease]; // 开始存档对象,存档的数据都会存储到NSMutableData中 [archiver encodeObject:person1 forKey:@"person1"]; [archiver encodeObject:person2 forKey:@"person2"]; // 存档完毕(一定要调用这个方法) [archiver finishEncoding]; // 将存档的数据写入文件 [data writeToFile:path atomically:YES];

NSData-从同一文件中恢复2个Person对象

恢复(解码)
// 从文件中读取数据
NSData *data = [NSData dataWithContentsOfFile:path];
// 根据数据,解析成一个NSKeyedUnarchiver对象 NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; Person *person1 = [unarchiver decodeObjectForKey:@"person1"]; Person *person2 = [unarchiver decodeObjectForKey:@"person2"]; // 恢复完毕 [unarchiver finishDecoding];

 

归档的封装

#import <Foundation/Foundation.h>
@interface NSObject (Addition) +(BOOL)keyedArchiver:(id)obj key:(NSString *)key; +(BOOL)keyedArchiver:(id)obj key:(NSString *)key path:(NSString *)path; +(id)keyedUnarchiver:(NSString *)key; +(id)keyedUnarchiver:(NSString *)key path:(NSString *)path; @end 

 

#define DefaultKeyedArchiverPath [NSString stringWithFormat:@"%@/Documents/DefaultKeyedArchiver.data", NSHomeDirectory()]

@implementation NSObject (Addition)

/**
 *  归档
 *
 *  @param obj 需要归档的类
 *  @param key 归档key * *  @return YES表示成功,NO表示失败 */ +(BOOL)keyedArchiver:(id)obj key:(NSString *)key { return [self keyedArchiver:obj key:key path:DefaultKeyedArchiverPath]; } /** * 归档 * *  @param obj 需要归档的类 *  @param key 归档key *  @param path 归档路劲 * *  @return YES表示归档成功,NO表示归档失败 */ +(BOOL)keyedArchiver:(id)obj key:(NSString *)key path:(NSString *)path { NSMutableData *tpData = [NSMutableData data]; NSKeyedArchiver *keyedArchiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:tpData]; [keyedArchiver encodeObject:obj forKey:key]; [keyedArchiver finishEncoding]; return [tpData writeToFile:path atomically:YES]; } /** * 解档 * *  @param key key * *  @return 解析的结果 */ +(id)keyedUnarchiver:(NSString *)key { return [self keyedUnarchiver:key path:DefaultKeyedArchiverPath]; } /** * 解档 * *  @param key 解挡key *  @param path 解挡路径 * *  @return 解析的结果 */ +(id)keyedUnarchiver:(NSString *)key path:(NSString *)path { NSMutableData *tpData = [NSMutableData dataWithContentsOfFile:path]; NSKeyedUnarchiver *keyedUnarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:tpData]; return [keyedUnarchiver decodeObjectForKey:key]; } @end

转载于:https://www.cnblogs.com/crash-wu/p/4932489.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值