浅析iOS中的归档与反归档

作者: 老实的大宝 | 来源:发表于2016-02-20 18:23 被阅读3938次

    今天我们要搞一搞iOS开发当中的归档和反归档,在进入正题之前,我们需要了解一下归档和反归档是干什么用的。

    所谓归档,最通用的定义就是存储有组织的数据,目的是为了长时间存放有组织的数据集。实际上就是将对象写入文件当中。下面我们学习第一种归档与反归档方法

    一、
    (1)归档

        NSArray *array = [NSArray arrayWithObjects:@1,@2,@3, nil];
        
        NSString *filePath = [NSHomeDirectory() stringByAppendingString:@"testFile.plist"];
        
        BOOL success = [NSKeyedArchiver archiveRootObject:array toFile:filePath];
        
        NSLog(@"%d",success);
        NSLog(@"%@",filePath);
    

    通过打印BOOL值来判断是否归档成功,也可以打印文件路径,通过Finder查找到文件夹来查看归档结果。

    归档结果.png

    (2)反归档

    NSString *filePath = [NSHomeDirectory() stringByAppendingString:@"testFile.plist"];
        
        id array = [NSKeyedUnarchiver unarchiveObjectWithFile:filepath];
        
        NSLog(@"%@",array);
    

    第一种方法比较简单,但是只能存储单个对象。
    第二种方法可以将多个对象归档成一个文件。

    二、

    (1)归档

    NSMutableArray *array = [NSMutableArray arrayWithObjects:@"BigDragon",@"BigBiao",@"BigBaby", nil];
        NSMutableData *data = [NSMutableData data];
        NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
        //编码
        [archiver encodeObject:array forKey:@"array"];
        [archiver encodeObject:@"Jason‘s friends" forKey:@"name"];
        
        //编码完成之后,对象已经存储到data之中。
        [archiver finishEncoding];
        
        NSString *filePath = [NSHomeDirectory() stringByAppendingPathComponent:@"array.plist"];
        BOOL success = [data writeToFile:filePath atomically:YES];
        NSLog(@"%d",success);```
    
    *(2)反归档*
    

    NSString *filePath = [NSHomeDirectory() stringByAppendingPathComponent:@"array.plist"];
    //读取归档数据
    NSData *data = [[NSData alloc] initWithContentsOfFile:filePath];

    //创建解归档对象,进行反归档
    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
    
    //反归档
    NSArray *array = [unarchiver decodeObjectForKey:@"array"];
    NSLog(@"%@",array);
    
    NSString *name = [unarchiver decodeObjectForKey:@"name"];
    NSLog(@"%@",name);```
    

    前两种方法我们归档的都是系统给定的类,那么如何归档我们自定义的类呢?

    (三)归档自定义对象

    美好的一天从创建一个Person类开始。 ——洋哥

    遵从洋哥的教诲,让我们先创建一个Person类吧。

    自定义类的归档需要遵守NSCoding协议,废话不多说,还是看代码吧。

    Person.h

    #import <Foundation/Foundation.h>
    
    // 给自定义类归档,首先要遵守NSCoding协议。
    @interface Person : NSObject<NSCoding>
    
    @property (nonatomic,strong) NSString *name;
    @property (nonatomic,assign) NSInteger age;
    @property (nonatomic,strong) NSString *gender;
    
    - (NSString *)description;
    
    @end```
    
    *Person.m*
    *.m文件中需要写encodeWithCoder和initWithCoder两个方法,分别在归档和反归档的时候调用。*
    

    import "Person.h"

    @implementation Person

    // 归档方法

    • (void)encodeWithCoder:(NSCoder *)aCoder
      {
      [aCoder encodeObject:self.name forKey:@"name"];
      [aCoder encodeInteger:self.age forKey:@"age"];
      [aCoder encodeObject:self.gender forKey:@"gender"];
      }
      // 反归档方法

    • (instancetype)initWithCoder:(NSCoder *)aDecoder
      {
      self = [super init];

      if (self != nil) {
      self.name = [aDecoder decodeObjectForKey:@"name"];
      self.age = [aDecoder decodeIntegerForKey:@"age"];
      self.gender = [aDecoder decodeObjectForKey:@"gender"];
      }
      return self;
      }

    • (NSString *)description
      {
      NSString *string = [NSString stringWithFormat:@"%@,%ld,%@",self.name,self.age,self.gender];
      return string;
      }
      @end```

    main函数
    写完Person的.h 和 .m 文件之后,接下来的就是在main函数中的操作了,我这里用的是ViewController,效果是一样的。

    #import "ViewController.h"
    #import "Person.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        Person *person = [[Person alloc]init];
        
        person.name = @"BigBaby";
        person.age = 16;
        person.gender = @"男";
        
        // 归档,调用归档方法
        NSString *filePath = [NSHomeDirectory() stringByAppendingString:@"person.plist"];
        BOOL success = [NSKeyedArchiver archiveRootObject:person toFile:filePath];
        NSLog(@"%d",success);
        
        // 反归档,调用反归档方法
        Person *per = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
        NSLog(@"%@",per);
        
        // Do any additional setup after loading the view, typically from a nib.
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }```
    *通过打印反归档解出来的BOOL值和对象per,可以验证是否归档和反归档成功。*

    相关文章

      网友评论

      • dongwenbo:请问在Model中写归档解档代码有什么作用呢,这个地方不太明白,我都是用mjextension
        老实的大宝:@dongwenbo 将model进行归档和反归档,需要遵从NSCoding协议,这两个方法是必须要写的,也是一定会用到的。
        dongwenbo:@老实的大宝 这个我明白,就是不太理解Model中写coder方法的作用是什么,我查到的说是可以保留用户状态,恢复用户状态用的,不明白是不是必须要写
        老实的大宝:@dongwenbo 你需要将model归档和反归档,在主函数中调用model的时候,需要用到这两个方法来实现归档和反归档,你能明白吗?
      • 78bd5ca7ec3f:有用
        老实的大宝:@meam 有用就好,你说有用我就开心了。
      • 落影loyinglin:配合runtime可以直接把所有属性归档
        落影loyinglin:@你要记得那个梦想 具体的代码 ,在我电脑上。手机不好打
        落影loyinglin:@你要记得那个梦想 通过runtime 可以访问到所有的属性,用for循环遍历属性数组,依次把属性放到nscoder。
        gggyyyccc:@月光族人_落影 怎么做?求教。 :pray:

      本文标题:浅析iOS中的归档与反归档

      本文链接:https://www.haomeiwen.com/subject/wubmkttx.html