iOS数据持久化之归档

如果我们需要对一个对象进行保存的话,我们就需要使用到归档 -- NSKeyedArchiver

下面从一个简单的例子来了解归档的使用


@protocol NSCoding

- (void)encodeWithCoder:(NSCoder *)aCoder;
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder; // NS_DESIGNATED_INITIALIZER

@end

从文档中了解到 NSCoding 主要有两个方法,一个是 encodeWithCoder 用于归档, 一个是 initWithCoder 用于解档

关于 NSSecureCoding 是为了数据类型安全考虑加入的, 需要实现 + (BOOL)supportsSecureCoding

NSObject 实现了一个 NSCoding 协议 就可以实现归档

首先创建一个 model 并且实现 NSCoding

ArticleModel.h

#import 

@interface ArticleModel : NSObject

@property (nonatomic, copy) NSString *title;

@property (nonatomic, copy) NSString *content;


@end

ArticleModel.m

#import "ArticleModel.h"

static NSString * const kArticleTitle = @"kArticleTitle";
static NSString * const kArticleContent = @"kArticleContent";

@implementation ArticleModel


- (id)init
{
    self = [super init];
    
    if (self) {
        
    }
    
    return self;
}

#pragma mark - 实现 NSSecureCoding 协议
/// NSSecureCoding 基于 NSCoding 保证了数据操作的安全(数据类型异常问题)

/// 归档 调用
- (void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:_title forKey:kArticleTitle];
    [aCoder encodeObject:_content forKey:kArticleContent];
}

/// 解档进行调用
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder
{
    /// 父类使用了 NSCoder 则使用 [super initWithCoder:decoder] 否则,只需要调用[super init]即可
    self = [super init];
    
    if (self)
    {
       /// 解码指定类型
        _title   = [aDecoder decodeObjectOfClass:[NSString class] forKey:kArticleTitle];
        _content = [aDecoder decodeObjectOfClass:[NSString class] forKey:kArticleContent];
    }
    
    return self;
}

+ (BOOL)supportsSecureCoding
{
    return YES;
}

@end

下面在 ViewController 中对articleModel 赋值后就可以进行归档的操作了

    self.articleModel = [NSKeyedUnarchiver unarchiveObjectWithFile:[self docPath]];

    [NSKeyedArchiver archiveRootObject:self.articleModel toFile:[self docPath]];
    

完整代码:

#import "ViewController.h"
#import "ArticleModel.h"

@interface ViewController ()

@property (nonatomic, strong) ArticleModel *articleModel;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self.view endEditing:YES];
}

- (IBAction)ArchiveMethod:(id)sender
{
    self.articleModel.title = _titleField.text;
    
    self.articleModel.content = _contentTextView.text;
    
    [NSKeyedArchiver archiveRootObject:self.articleModel toFile:[self docPath]];
}

- (IBAction)UnArchiveMethod:(id)sender
{
    self.articleModel = [NSKeyedUnarchiver unarchiveObjectWithFile:[self docPath]];
    
    _titleField.text = _articleModel.title;
    _contentTextView.text = _articleModel.content;
}

- (NSString *)docPath
{
    NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    
    docPath = [docPath stringByAppendingPathComponent:@"ArticleFile"];
    
    NSLog(@"归档地址: %@", docPath);
    
    return docPath;
}

#pragma mark - setters and getters
- (ArticleModel *)articleModel
{
    if (!_articleModel) {
        _articleModel = [[ArticleModel alloc] init];
    }
    
    return _articleModel;
}

@end

完整demo ,在这里

你可能感兴趣的:(iOS数据持久化之归档)