OC基础-Archiver

﹥>﹥吖頭↗ 提交于 2020-03-01 03:28:35

概述

Archiver,即是归档。归档是将OC对象进行序列化,通过密文形式把数据保存到硬盘,所以安全性比较好。不同对象的归档方式不一样,大概分为以下几种:单一对象、多对象和模型对象。

单一对象

这里单一对象指的是Foundation框架中已有的对象,如NSString、NSNumber、NSArray等等,下面是具体例子:

void archiverDemo() {
    NSString *name = @"zhangsan";
    NSNumber *number = @(100);
    NSArray *array = @[@"lisi", @"wangwu", @"zhaoliu"];
    NSDictionary *dictionary = @{@"name":@"xiaoming", @"age":@"22"};
    
    // 将所有对象存放到数组,归档该数组
    NSArray *datas = @[name, number, array, dictionary];
    
    // 进行归档
    NSString *filePath = [NSHomeDirectory() stringByAppendingPathComponent:@"datas.archiver"];
    if ([NSArchiver archiveRootObject:datas toFile:filePath]) {
        NSLog(@"归档成功!");
    } else
        NSLog(@"归档失败!");
    
    // 解档
    NSArray *unarchiverDatas = [NSUnarchiver unarchiveObjectWithFile:filePath];
    NSLog(@"%@", unarchiverDatas);
}

上面的例子其实只对一个对象进行了归档操作,即是datas数组对象。假如数据都是分散的,那么可以采用以下的方式进行归档。

多对象

依然采用上面的数据,不过这次没有创建datas数组,而是直接对所有数据进行归档:

void mutableDataArchiverDemo() {
    // 进行归档的数据
    NSString *name = @"zhangsan";
    NSNumber *number = @(100);
    NSArray *array = @[@"lisi", @"wangwu", @"zhaoliu"];
    NSDictionary *dictionary = @{@"name":@"xiaoming", @"age":@"22"};
    
    // 采用NSMutableData来填充数据
    NSMutableData *mutableDatas = [NSMutableData data];
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:mutableDatas];
    
    // 设置数据的关键字属性
    [archiver encodeObject:name forKey:@"name"];
    [archiver encodeObject:number forKey:@"number"];
    [archiver encodeObject:array forKey:@"array"];
    [archiver encodeObject:dictionary forKey:@"dictionary"];
    
    [archiver finishEncoding];
    
    // 进行归档
    NSString *filePath = [NSHomeDirectory() stringByAppendingPathComponent:@"mutableDatas.archiver"];
    if ([data writeToFile:filePath atomically:YES]) {
        NSLog(@"归档成功!");
    } else
        NSLog(@"归档失败!");
    
    // 解档
    NSData *unarchiverDatas = [NSData dataWithContentsOfFile:filePath];
    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:unarchiverDatas];
    
    // 通过关键字获得对应数据
    NSArray *arr = [unarchiver decodeObjectForKey:@"array"];
    NSLog(@"%@", arr);
}

模型对象

对模型对象进行归档时,需引入NSCoding协议,并实现initWithCoder:和encodeWithCoder:方法。下面创建一个Person类作为例子。

// Person.h
#import <Foundation/Foundation.h>

@interface Person : NSObject <NSCoding>

@property (nonatomic, readwrite, copy) NSString *Name;
@property (nonatomic, readwrite, weak) NSNumber *Age;
@property (nonatomic, readwrite, copy) NSString *Address;
@property (nonatomic, readwrite, weak) NSNumber *Score;
@property (nonatomic, readwrite, copy) NSString *Url;

@end

在.m文件中实现编码和解码两个方法:

// Person.m
// Person解码方法
- (instancetype)initWithCoder:(NSCoder *)coder
{
    self = [super init];
    if (self) {
        self.Name = [coder decodeObjectForKey:@"Name"];
        self.Age = [coder decodeObjectForKey:@"Age"];
        self.Address = [coder decodeObjectForKey:@"Address"];
        self.Score = [coder decodeObjectForKey:@"Score"];
        self.Url = [coder decodeObjectForKey:@"Url"];
    }
    return self;
}
// Person编码方法
- (void)encodeWithCoder:(NSCoder *)coder
{
    [coder encodeObject:self.Name forKey:@"Name"];
    [coder encodeObject:self.Age forKey:@"Age"];
    [coder encodeObject:self.Address forKey:@"Address"];
    [coder encodeObject:self.Score forKey:@"Score"];
    [coder encodeObject:self.Url forKey:@"Url"];
}

然后在main.m文件导入Person.h,并通过一个测试方法来进行归档解档操作:

void keyedArchiverDemo() {
    // 创建一个Person对象
    Person *person = [[Person alloc] init];
    person.Name = @"zhangsan";
    person.Age = @(22);
    person.Address = @"Guangzhou";
    person.Score = @(80);
    person.Url = @"http://www.baidu.com";

    // 进行归档
    NSString *filePath = [NSHomeDirectory() stringByAppendingPathComponent:@"person.archiver"];
    if([NSKeyedArchiver archiveRootObject:person toFile:filePath])
        NSLog(@"归档成功!");
    else
        NSLog(@"归档失败!");

    // 解档
    Person *p = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
    NSLog(@"%@", p);
}

如果模型对象属性过多,可以创建一个数组来存放这些属性关键字,然后采用forin来遍历关键字数组,并通过setValue: forKey:和valueForKey:的方式来进行设置和访问Person属性:

// Person.m
// Person解码方法
- (instancetype)initWithCoder:(NSCoder *)coder
{
    NSArray *keys = @[@"Name", @"Age", @"Address", @"Score", @"Url"];
    self = [super init];
    if (self) {
        for (NSString *key in keys) {
            [self setValue:[coder decodeObjectForKey:key] forKey:key];
        }
    }
    return self;
}
// Person编码方法
- (void)encodeWithCoder:(NSCoder *)coder
{
    NSArray *keys = @[@"Name", @"Age", @"Address", @"Score", @"Url"];
    for (NSString *key in keys) {
        [coder encodeObject:[self valueForKey:key] forKey:key];
    }
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!