zoukankan      html  css  js  c++  java
  • ios学习笔记——对象归档

    对象归档是一种序列化方式。为了便于数据传输,先将归档对象序列化为一个文件,然后再通过反归档将数据恢复到对象中。

    归档技术可以实现数据的持久化,不过在大量数据和频繁读写的情况下,它就不太适合了。

    对一个对象进行归档的条件是:改对象的类必须实现NSCoding协议,而且每个成员对象应该是基本数据类型或都是实现NSCoding协议的某个类的实例。

    一、使用NSKeyedArchiver进行简单归档


    1     NSString * path = NSHomeDirectory();
    2     NSString * filePath = [path stringByAppendingPathComponent:@"sjz.txt"];
    3     //归档,这里可以是NSString、NSDate、NSArray、NSDictionary等
    4     [NSKeyedArchiver archiveRootObject:@"sjz" toFile:filePath];
    5     
    6     //反归档
    7     NSString * str = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];

    这种方式在写入、读出数据之前对数据惊醒序列化、反序列化操作,可以对基本类型数据进行归档。但是这样只能把一个对象归档进一个文件中。

    二、多个数据的归档


    当有多个数据的时候,我们就需要NSData的帮助了。

    NSData封装了字典数据的缓存类,提供了数据文件的方法:

    + (instancetype)dataWithContentsOfFile:(NSString *)path

    + (instancetype)dataWithContentsOfFile:(NSString *)path  options:(NSDataReadingOptions)mask error:(NSError * _Nullable *)errorPtr

    - (instancetype)initWithContentsOfFile:(NSString *)path

    - (instancetype)initWithContentsOfFile:(NSString *)path options:(NSDataReadingOptions)mask error:(NSError * _Nullable *)errorPtr

    上面四个方法用于从文件中读取数据创建NSData对象

    - (BOOL)writeToFile:(NSString *)path atomically:(BOOL)atomically

    - (BOOL)writeToFile:(NSString *)path options:(NSDataWritingOptions)mask error:(NSError * _Nullable *)errorPtr

    这两个方法用于将NSData里的数据写的文件中去

     1 //文件路径
     2     NSString * path = NSHomeDirectory();
     3     NSString * filePath = [path stringByAppendingPathComponent:@"sjz.txt"];
     4     
     5     NSString * str = @"小明";
     6     NSString * age = @"10";
     7     NSArray * arr = [NSArray arrayWithObjects:@"123", @"456", @"789", nil];
     8     NSInteger integer = 10;
     9     
    10     //归档
    11     NSMutableData * data = [[NSMutableData alloc] init];
    12     NSKeyedArchiver * archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    13     [archiver encodeObject:str forKey:@"name"];
    14     [archiver encodeObject:age forKey:@"age"];
    15     [archiver encodeObject:arr forKey:@"arr"];
    16     [archiver encodeInteger:integer forKey:@"integer"];
    17     [archiver finishEncoding];
    18     [data writeToFile:filePath atomically:YES];
    19     
    20     //反归档
    21     NSMutableData * unData = [[NSMutableData alloc] initWithContentsOfFile:filePath];
    22     NSKeyedUnarchiver * unArchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:unData];
    23     NSString * name = [unArchiver decodeObjectForKey:@"name"];
    24     NSString * ageStr = [unArchiver decodeObjectForKey:@"age"];
    25     NSArray  * array = [unArchiver decodeObjectForKey:@"arr"];
    26     NSInteger intt = [unArchiver decodeIntegerForKey:@"integer"];
    27     [unArchiver finishDecoding];
    28     
    29     NSLog(@"name = %@, age = %@", name, ageStr);
    30     NSLog(@"%@", array);
    31     NSLog(@"%ld", intt);

    归档时,我们先将所需的数据归档到NSData中,再将NSData数据写到文件中。

    反归档时,我们先从文件中读取数据到NSData中,再根据键值烦归档

    第三、自定义对象的归档


    上边说的是基本对象的归档,但是我们自己定义的实例对象怎么归档呢?

    但我们按Home键将程序后台运行时,很多情况下我们要将数据保存,当程序恢复时,数据重新加载,那么归档是一个好的选择。

    我们自定义的类想要实现归档与反归档,必须实现NSCoding协议,并实现协议中的两个方法:- (void)encodeWithCoder:(NSCoder *)aCoder 和 - (instancetype)initWithCoder:(NSCoder *)aDecoder

    自定义类:

    1 #import <Foundation/Foundation.h>
    2 
    3 @interface JZModel : NSObject <NSCoding>
    4 
    5 @property (nonatomic, strong) NSString * name;
    6 @property (nonatomic, assign) NSInteger age;
    7 @property (nonatomic, strong) NSString * address;
    8 
    9 @end
     1 #import "JZModel.h"
     2 
     3 @implementation JZModel
     4 
     5 //必须实现,归档
     6 - (void)encodeWithCoder:(NSCoder *)aCoder
     7 {
     8     [aCoder encodeObject:_name forKey:@"name"];
     9     [aCoder encodeInteger:_age forKey:@"age"];
    10     [aCoder encodeObject:_address forKey:@"address"];
    11 }
    12 
    13 //必须实现,反归档
    14 - (instancetype)initWithCoder:(NSCoder *)aDecoder
    15 {
    16     self = [super init];
    17     if(self){
    18         _name = [aDecoder decodeObjectForKey:@"name"];
    19         _age = [aDecoder decodeIntegerForKey:@"age"];
    20         _address = [aDecoder decodeObjectForKey:@"address"];
    21     }
    22     
    23     return self;
    24 }
    25 
    26 
    27 - (NSString *)description
    28 {
    29     return [NSString stringWithFormat:@"姓名:%@,年龄:%ld,地址:%@", self.name, self.age, self.address];
    30 }
    31 
    32 @end

    实现归档与反归档的代码:

     1 NSString * homePath = NSHomeDirectory();
     2     NSString * filePath = [homePath stringByAppendingPathComponent:@"sjz.plist"];
     3     
     4     JZModel * model = [[JZModel alloc] init];
     5     model.name = @"jz";
     6     model.age = 20;
     7     model.address = @"河北大街";
     8     
     9     //归档
    10     NSMutableData * data = [[NSMutableData alloc] init];
    11     NSKeyedArchiver * archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    12     [archiver encodeObject:model forKey:@"model"];
    13     [archiver finishEncoding];
    14     [data writeToFile:filePath atomically:YES];
    15     
    16     
    17     //反归档
    18     NSMutableData * data1 = [[NSMutableData alloc] initWithContentsOfFile:filePath];
    19     NSKeyedUnarchiver * unArchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data1];
    20     JZModel * model1 = [unArchiver decodeObjectForKey:@"model"];
    21     [unArchiver finishDecoding];
    22     
    23     NSLog(@"%@", model1);

    输出结果:

  • 相关阅读:
    ubuntu 安装 库文件
    java接口定义的静态方法和默认如何在类实现的时候使用
    通过java的i/o机制进行图片流的存储以及对网络图片的存储
    java的两种冒泡算法
    Java的Integer和int有什么区别
    使用jq的ajax实现对xml文件的读取
    typescript中的工具 tsd
    使用reactjs遇到Warning: setState(...): Can only update a mounted or mounting component.
    在create-react-app的脚手架里面使用scss
    使用fetch-jsonp进行跨域以及参数的传递
  • 原文地址:https://www.cnblogs.com/sjzlovecj/p/4837671.html
Copyright © 2011-2022 走看看