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];
    }
}
相關文章
相關標籤/搜索