归档
一:什么是归档
对象归档是将对象归档以文件的形式保存到磁盘中(也称为序列化,持久化)使用的时候读取该文件的保存路径读取文件的内容(也称为接档,反序列化)
对象归档的文件是保密的磁盘上无法查看文件中的内容,而属性列表是明文的可以查看
1,使用archiveRootObject进行简单地归档和解档(对一个对象进行归档)
- (void)viewDidLoad {
[super viewDidLoad];
NSString *str = @"afa";
NSString *astr = @"111";
NSArray *Array = [NSArray arrayWithObjects:str, astr, nil];
//归档
NSString *Path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filename = [Path stringByAppendingPathComponent:@"test"];
[NSKeyedArchiver archiveRootObject:Array toFile:filename];
//解档
NSArray *arr = [NSKeyedUnarchiver unarchiveObjectWithFile: filename];
str = [arr objectAtIndex:0];
astr = [arr objectAtIndex:1];
NSLog(@"str:%@",str);
NSLog(@"astr:%@",astr);
}
2,对多个对象的归档(对基本类型数据)
归档(写入数据)
step1:准备数据
- CGPoint point = CGPointMake(1.0, 2.0);
- NSString *info = @"坐标原点";
- NSInteger value = 10;
- NSString *multiHomePath = [NSHomeDirectory() stringByAppendingPathComponent:@"multi.archiver"];
- NSMutableData *data = [[NSMutableData alloc]init];
- NSKeyedArchiver *archvier = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];
step2:对多个对象进行归档
- [archvier encodeCGPoint:point forKey:@"kPoint"];
- [archvier encodeObject:info forKey:@"kInfo"];
- [archvier encodeInteger:value forKey:@"kValue"];
- [archvier finishEncoding];
- [data writeToFile:multiHomePath atomically:YES];
解档(路径中获得数据构造NSKeyedUnarchiver实例,使用decodeXXXForKey方法获得文件中的对象。)
- NSMutableData *dataR = [[NSMutableData alloc]initWithContentsOfFile:multiHomePath];
- NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:dateR];
- CGPoint pointR = [unarchiver decodeCGPointForKey:@"kPoint"];
- NSString *infoR = [unarchiver decodeObjectForKey:@"kInfo"];
- NSInteger valueR = [unarchiver decodeIntegerForKey:@"kValue"];
- [unarchiver finishDecoding];
- NSLog(@"%f,%f,%@,%d",pointR.x,pointR.y,infoR,valueR);
3,对自定义对象进行归档
step1:自定义一个实体类Archive
Archive.h
- #import <Foundation/Foundation.h>
- @interface Archive : NSObject
- @property (copy,nonatomic) NSString *name;
- @property NSInteger age;
- @property (copy,nonatomic) NSString *address;
- @property (copy,nonatomic) UIImage *photo;
- @end
Archive.m
- #import "Archive.h"
- #define kNameKey @"NameKey"
- #define kAgeKey @"AgeKey"
- #define kAddress @"AddressKey"
- #define kPhotoKey @"PhotoKey"
- @implementation Archive
- #pragma mark - NSCoding
- - (void)encodeWithCoder:(NSCoder *)aCoder {
- [aCoder encodeObject:_name forKey:kNameKey];
- [aCoder encodeInteger:_age forKey:kAgeKey];
- [aCoder encodeObject:_address forKey:kAddress];
- [aCoder encodeObject:_photo forKey:kPhotoKey];
- }
- - (id)initWithCoder:(NSCoder *)aDecoder {
- if (self = [super init]) {
- _name = [aDecoder decodeObjectForKey:kNameKey];
- _age = [aDecoder decodeIntegerForKey:kAgeKey];
- _address = [aDecoder decodeObjectForKey:kAddress];
- _photo = [aDecoder decodeObjectForKey:kPhotoKey];
- }
- return self;
- }
- #pragma mark - NSCoping
- - (id)copyWithZone:(NSZone *)zone {
- Archive *copy = [[[self class] allocWithZone:zone] init];
- copy.name = [self.name copyWithZone:zone];
- copy.age = self.age;
- copy.address = [self.address copyWithZone:zone];
- copy.photo = self.photo;
- return copy;
- }
- @end
Archive实现了三个委托方法1)encodeWithCoder: 2)initWithCoder: 3)copyWithZone:
1)encodeWithCoder
Encodes the receiverusing a given archiver
通过一个给定的archiver把消息接收者进行编码。
当接收到encodeObject消息的时候,类终端encodeWithCoder方法被调用。
2)initWithCoder
Returns an objectinitialized from data in a given unarchiver. (required)
从一个给定unarchiver的数据中返回一个初始化对象。
3)copyWithZone
Returnsa new instance that’s a copy of the receiver
返回消息接收者的一个复制的新实例。
SDK的概念就是这样,下面看看这个自定义类归档的具体代码,其实和多个对象的归档是一样的。。。
step2:归档:
- //保存图片与归档
- - (IBAction)save:(id)sender {
- //准备数据
- NSString *name = @"小杨在玩iOS";
- NSInteger age = 22;
- NSString *address = @"你猜我在哪~";
- UIImage *photo = [UIImage imageNamed:@"loginman.jpg"];
- //存储数据到类
- Archive *archivingData = [[Archive alloc] init];
- archivingData.name = name;
- archivingData.age = age;
- archivingData.address = address;
- archivingData.photo = photo;
- //归档
- NSMutableData *data = [[NSMutableData alloc] init];
- NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
- [archiver encodeObject:archivingData forKey:kArchivingDataKey]; // archivingDate的encodeWithCoder
- 方法被调用
- [archiver finishEncoding];
- //写入文件
- [data writeToFile:self.archivingFilePath atomically:YES];
- }
step3:接档:
- - (IBAction)loadArchive:(id)sender {
- NSData *data = [[NSMutableData alloc] initWithContentsOfFile:self.archivingFilePath];
- NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
- //获得类
- Archive *archivingData = [unarchiver decodeObjectForKey:kArchivingDataKey];// initWithCoder方法被调用
- [unarchiver finishDecoding];
- //读取的数据
- NSString *name = archivingData.name;
- NSInteger age = archivingData.age;
- NSString *address = archivingData.address;
- self.imageView.image = archivingData.photo;
- NSLog(@"%@||%d||%@",name,age,address);
- }