归档时iOS中一种常见的存储文件的方式。在iOS中,归档可以将一切对象,包括自定义的对象都存储在文件中,其中常见的三种归档方式为简单归档,NSData归档,自定义归档。
-
简单归档
简单归档就是把常见的字符串,字典,数组等不经过转化直接写入文件。我们先创建一个沙盒中的路径,这个路径就是我们将要存放字符串,字典,数组等的地方。然后我们再利用NSKeyArchieve的类方法archiveRootObject: toFile:
将字符串或数组写入到我们创建的路径的文件中。archiveRootObject: toFile:
这个方法会自动创建文件。下面是具体的步骤:
NSArray *array = @[@1, @2, @3];
//创建一个沙盒地址
NSString *path = [NSString stringWithFormat:@"%@/documents/arrayFile", NSHomeDirectory()];
//这句话会自动创建path对应的文件,并将array写入到该文件中去,完成归档
[NSKeyedArchiver archiveRootObject:array toFile:path];
//根据文件地址实现解档
NSArray *array1 = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
-
NSData归档
这种归档方式是先创建一个可变的data对象,然后根据这个对象来创建一个NSKeyArchieve的实例对象,然后利用这个实例对象对多个基本数据类型进行归档,之后再写入一个指定的沙盒路径。这个方式的好处是我们可以写入多个基本数据类型到同一个文件。下面是具体的实现步骤:
//创建存放路径
NSString *dataPath = [NSString stringWithFormat:@"%@/documents/dataFile", NSHomeDirectory()];
//创建可变的data
NSMutableData *mutableData = [[NSMutableData alloc] init];
//通过data创建NSKeyedArchiver的实例对象
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:mutableData];
//进行归档
[archiver encodeObject:@"string" forKey:@"string"];
[archiver encodeBool:YES forKey:@"sex"];
[archiver encodeInt:5 forKey:@"age"];
[archiver finishEncoding];
//写入文件
[mutableData writeToFile:dataPath atomically:YES];
//解归档
NSData *dataout = [NSData dataWithContentsOfFile:dataPath];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:dataout];
NSString *string = [unarchiver decodeObjectForKey:@"string"];
BOOL sex = [unarchiver decodeBoolForKey:@"sex"];
int age = [unarchiver decodeIntForKey:@"age"];
-
自定义归档
在第一个例子中如果array中的内容不是NSNumber类型的数据,而是自定义的对象呢?还能成功的归档吗?答案是否定的。比如说我们有一个Person类,它有两个属性,name和age,array中存放的即两个Person类的实例。为了实现转码成功,在Person类中要实现NSCoding协议,在归档的过程中转码,才能归档成功
NSCoding协议有两个方法,且都是require。自定义的类中实现了这两个方法才能对自定义的对象进行归档。这两个方法是:
//对自定义的类内部的属性变量进行转码
-(void)encodeWithCoder:(NSCoder *)aCoder;
//对自定义的类中的属性变量根据关键字进行逆转码
-(id)initWithCoder:(NSCoder *)aDecoder;
下面就看一下具体的实现:
//Person.h
@interface Person : NSObject <NSCoding>
@property (nonatomic, strong)NSString *name;
@property (nonatomic, assign)int age;
- (instancetype)initWithName:(NSString *)name age:(int)age;
//Person.m
#import "Person.h"
@implementation Person
- (instancetype)initWithName:(NSString *)name age:(int)age{
self = [super init];
if(self){
_name = name;
_age = age;
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:_name forKey:@"name"];
[aCoder encodeInt:_age forKey:@"age"];
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder{
self = [super init];
if(self){
_name = [aDecoder decodeObjectForKey:@"name"];
_age = [aDecoder decodeIntForKey:@"age"];
}
return self;
}
@end
Person *person1 = [[Person alloc] initWithName:@"小花" age:8];
Person *person2 = [[Person alloc] initWithName:@"小明" age:9];
NSArray *array = @[person1, person2];
NSString *path = [NSString stringWithFormat:@"%@/documents/custom", NSHomeDirectory()];
[NSKeyedArchiver archiveRootObject:array toFile:path];
NSArray *array1 = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
网友评论