[OC]-数据缓存(归档/解档)

一、使用archiveRootObject进行简单的归档

使用NSKeyedArichiver进行归档、NSKeyedUnarchiver进行接档,这种方式会粗体在写入、读出数据之前对数据进行序列化、反序列化操作。

归档:

NSString *homeDictionary = NSHomeDirectory();//获取根目录  

NSString *homePath  = [homeDictionary stringByAppendingPathComponent:@"atany.archiver"];//添加储存的文件名  

BOOL flag = [NSKeyedArchiver archiveRootObject:@”归档” toFile:homePath];//归档一个字符串  

这种方式可以对字符串、数字等进行归档,当然也可以对NSArray与NSDictionary进行归档。返回值Flag标志着是否归档成功,YES为成功,NO为失败。

解档:

[NSKeyedUnarchiver unarchiveObjectWithFile:homePath]  

使用NSKeyedUnarchiver进行接档(反序列化)。

这种归档的方式存在一个缺点:只能把一个对象归档进一个文件中,那么怎么对多个对象进行归档呢?


二、对自定义对象进行归档:

以实现登录功能为例:

1、新建model类,继承于NSObject类:

  1. 声明归档存储所需的属性:principal;unitId;realName;loginName;
  2. 遵循<NSCoding,NSCopying>协议,并实现必要的方法:
  • 归档时调用:**- (void)encodeWithCoder:(NSCoder )aCoder;*
    》通过一个给定的archiver把消息接收者进行编码。
    》当接收到encodeObject消息的时候,类终端encodeWithCoder方法被调用。

  • 解档时调用:**- (instancetype)initWithCoder:(NSCoder )aDecoder;*
    》从一个给定unarchiver的数据中返回一个初始化对象。

  • <NSCopying>协议方法:**-(id)copyWithZone:(NSZone )zone;* 》返回消息接收者的一个复制的新实例。

.h

#import <Foundation/Foundation.h>

@interface LoginInfoModel : NSObject<NSCoding,NSCopying>

@property (nonatomic , strong) NSString *principal;
@property (nonatomic , strong) NSString *unitId;
@property (nonatomic , strong) NSString *realName;
@property (nonatomic , strong) NSString *loginName;

@end

.m

#import "LoginInfoModel.h"

@implementation LoginInfoModel

//归档时调用
- (void)encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeObject:self.principal forKey:@"principal"];
    [aCoder encodeObject:self.unitId forKey:@"unitId"];
    [aCoder encodeObject:self.realName forKey:@"realName"];
    [aCoder encodeObject:self.loginName forKey:@"loginName"];
}

//解档时调用
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    if (self = [super init]) {
        _principal = [aDecoder decodeObjectForKey:@"principal"];
        _unitId = [aDecoder decodeObjectForKey:@"unitId"];
        _realName = [aDecoder decodeObjectForKey:@"realName"];
        _loginName = [aDecoder decodeObjectForKey:@"loginName"];
    }
    return self;
}

-(id)copyWithZone:(NSZone *)zone {
    LoginInfoModel *copy = [[[self class] allocWithZone:zone] init];  
    copy.principal = [self.principal copyWithZone:zone];  
    copy.unitId = [self.unitId copyWithZone:zone];  
    copy.realName = [self.realName copyWithZone:zone];  
    copy.loginName = [self.loginName copyWithZone:zone];  
    return copy; 
}

@end

2、归档

  • 在需要调取存档的位置进行存档相关操作(如:在登录成功后,拿到登录信息数据,进行存档。)
  • code == 200,代表登录成功(与服务端code码对应就ok);
if (status == 200) {
            NSDictionary *params = [response valueForKey:@"data"];

            //filePath:归档后保存的位置
            NSString *filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true).firstObject stringByAppendingPathComponent:@"/loginInfo/info.plist"];

            LoginInfoModel *info = [[LoginInfoModel alloc] init];
            info.principal = params[@"principal"];
            info.unitId = params[@"unitId"];
            info.realName = params[@"realName"];
            info.loginName = params[@"loginName"];

            //归档:此时会调用LoginInfoModel中的【归档】方法
            NSMutableData *data = [[NSMutableData alloc] init];
            NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
            [archiver encodeObject:info forKey:@"loginInfo"];
            [archiver finishEncoding];

            //写入文件
            BOOL isWrited = [data writeToFile:filePath atomically:true];
            if (isWrited) {
                //写入成功
            } else {
                //写入失败
            }
            
        } else {
            //error
            //登录异常
        }

3、解档

在需要读取时,进行以下操作:

    //在归档文件夹路径下(即之前的filePath),读取文件(解档)
    NSMutableData *data = [[NSMutableData alloc] initWithContentsOfFile:LoginInfoPath];
    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
    LoginInfoArchive *loginInfo = [unarchiver decodeObjectForKey:LoginUnarchiverKey];
    [unarchiver finishDecoding];
    //读取数据(使用)
    NSString *priprincipal = loginInfo.principal;
    NSString *unitId = loginInfo.unitId;
    NSString *realName = loginInfo.realName;
    NSString *loginName = loginInfo.loginName;
    NSLog(@"priprincipal=%@",priprincipal);
    NSLog(@"unitId=%@",unitId);
    NSLog(@"realName=%@",realName);
    NSLog(@"loginName=%@",loginName);

》要将一个自定义的类进行归档,那么类里面的每个属性都必须是可以被归档的,如果是不能归档的类型,我们可以把他转化为NSValue进行归档,然后在读出来的时候在转化为相应的类。

猜你喜欢

转载自my.oschina.net/xiaoLoo/blog/1648971
今日推荐