iOS中三种归档(NSKeyArchieve)方式总结

雪山飞狐_91ae 2019-02-28 10:09:12 606

归档时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];


作者:雪山飞狐_91ae
链接:https://www.jianshu.com/p/680e0ebb6253
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。