OC基础-Archiver

概述

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文件中实现编码和解码两个方法:atom

// 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,并经过一个测试方法来进行归档解档操做:code

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];
    }
}
相关文章
相关标签/搜索