zoukankan      html  css  js  c++  java
  • iOS开发

    归档与恢复归档

    归档,英文Archiver[‘ɑrkɪvə],这里指的是将OC的对象存储为一个文件或者网络上的一个数据块。
    恢复归档。英文UnArchiver,指的是将一个来自文件或网络的归档数据块恢复成内存中的一个OC对象。


    归档和恢复主要用于对自己定义类型对象进行存储。在程序暂停或关闭前保存自己定义数据。在程序又一次恢复状态或启动后读取存储的自己定义数据。
    支持归档和恢复的类必须实现NSCoding协议,再由NSKeyedArchiver和NSKeyedUnarchiver类进行转换。将对象转换为数据流
    其他语言,如java/.net 将此技术称为序列化。

    归档集合类型

    IOS 非常多内置类型都默认实现了归档功能。如NSNumber,NSArray,NSDictionary,NSString,NSData等。
    定义NSArray或NSDicitionary类型,初始化数据后。调用NSKeyedArchiver 类的archiveRootObject 传入file路径,就可以将当前NSArray对象完善的保存到文件系统中。

    读取归档数据,使用NSKeydUnarchiver类unarchiveObjectWithFile方法能够直接从文件读回数据,并返回NSArray对象 NSKeyedArchiver和NSKeyedUnarchiver类都是将对象属性和值以key|value的方式顺序存储和读取的。

    非常多时候我们须要归档和恢复自己定义对象,因此须要让自己定义对象实现归档功能
    实现归档仅仅须要遵循(实现)NSCoding协议或是NSCoding的子协议。

    NSKeyedArchiver

    假设对象是NSString、NSDictionary、NSArray、NSData、NSNumber等类型,能够直接用NSKeyedArchiver进行归档和恢复
    不是全部的对象都能够直接用这样的方法进行归档,仅仅有遵守了NSCoding协议的对象才干够
    NSCoding协议有2个方法:
    encodeWithCoder:
    每次归档对象时,都会调用这种方法。

    一般在这种方法里面指定怎样归档对象中的每一个实例变量,能够使用encodeObject:forKey:方法归档实例变量
    initWithCoder:
    每次从文件里恢复(解码)对象时,都会调用这种方法。

    一般在这种方法里面指定怎样解码文件里的数据为对象的实例变量,能够使用decodeObject:forKey方法解码实例变量

    有时须要将多个对象归档到一个文件,此时我们须要使用NSMutableData作为缓冲存储对象。


    先将对象归档到NSData中。再将NSData写入到文件里。

    NSKeyedArchiver-归档NSArray

    归档一个NSArray对象到Documents/array.archive
    NSArray *array = [NSArray arrayWithObjects:@”a”,@”b”,nil];
    [NSKeyedArchiver archiveRootObject:array toFile:path];
    
    恢复(解码)NSArray对象
    NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithFile:path]

    NSKeyedArchiver-归档Person对象(Person.h)

    @interface Person : NSObject<NSCoding>
    @property (nonatomic, copy) NSString *name;
    @property (nonatomic, assign) int age;
    @property (nonatomic, assign) float height;
    @end
    

    NSKeyedArchiver-归档Person对象(Person.m)

    @implementation Person
    - (void)encodeWithCoder:(NSCoder *)encoder {
        [encoder encodeObject:self.name forKey:@"name"];
        [encoder encodeInt:self.age forKey:@"age"];
        [encoder encodeFloat:self.height forKey:@"height"];
    }
    - (id)initWithCoder:(NSCoder *)decoder {
        self.name = [decoder decodeObjectForKey:@"name"];
        self.age = [decoder decodeIntForKey:@"age"];
        self.height = [decoder decodeFloatForKey:@"height"];
        return self;
    }
    - (void)dealloc {
        [super dealloc];
        [_name release];
    }
    @end
    

    NSKeyedArchiver-归档Person对象(编码和解码)

    //归档(编码)
    Person *person = [[[Person alloc] init] autorelease];
    person.name = @"wangzhaolu";
    person.age = 26;
    person.height = 1.78f;
    [NSKeyedArchiver archiveRootObject:person toFile:path];
    //恢复(解码)
    Person *person = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
    

    NSKeyedArchiver-归档对象的注意

    假设父类也遵守了NSCoding协议,请注意:
    应该在encodeWithCoder:方法中加上一句
    [super encodeWithCode:encode];
    确保继承的实例变量也能被编码,即也能被归档
    应该在initWithCoder:方法中加上一句
    self = [super initWithCoder:decoder];
    确保继承的实例变量也能被解码。即也能被恢复
    

    NSData

    使用archiveRootObject:toFile:方法能够将一个对象直接写入到一个文件里,但有时候可能想将多个对象写入到同一个文件里,那么就要使用NSData来进行归档对象
    NSData能够为一些数据提供暂时存储空间,以便随后写入文件,或者存放从磁盘读取的文件内容。

    能够使用[NSMutableData data]创建可变数据空间
    这里写图片描写叙述

    NSData-归档2个Person对象到同一文件里

    //归档(编码)
    // 新建一块可变数据区
    NSMutableData *data = [NSMutableData data];
    // 将数据区连接到一个NSKeyedArchiver对象
    NSKeyedArchiver *archiver = [[[NSKeyedArchiver alloc] initForWritingWithMutableData:data] autorelease];
    // 開始存档对象,存档的数据都会存储到NSMutableData中
    [archiver encodeObject:person1 forKey:@"person1"];
    [archiver encodeObject:person2 forKey:@"person2"];
    // 存档完成(一定要调用这种方法)
    [archiver finishEncoding];
    // 将存档的数据写入文件
    [data writeToFile:path atomically:YES];
    

    NSData-从同一文件里恢复2个Person对象

    恢复(解码)
    // 从文件里读取数据
    NSData *data = [NSData dataWithContentsOfFile:path];
    // 依据数据,解析成一个NSKeyedUnarchiver对象
    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
    Person *person1 = [unarchiver decodeObjectForKey:@"person1"];
    Person *person2 = [unarchiver decodeObjectForKey:@"person2"];
    // 恢复完成
    [unarchiver finishDecoding];
    

    归档的封装

    #import <Foundation/Foundation.h>
    @interface NSObject (Addition)
    
    
    +(BOOL)keyedArchiver:(id)obj key:(NSString *)key;
    
    +(BOOL)keyedArchiver:(id)obj key:(NSString *)key path:(NSString *)path;
    
    +(id)keyedUnarchiver:(NSString *)key;
    
    +(id)keyedUnarchiver:(NSString *)key path:(NSString *)path;
    
    @end
    
    #define DefaultKeyedArchiverPath [NSString stringWithFormat:@"%@/Documents/DefaultKeyedArchiver.data", NSHomeDirectory()]
    
    @implementation NSObject (Addition)
    
    /**
     *  归档
     *
     *  @param obj 须要归档的类
     *  @param key 归档key
     *
     *  @return YES表示成功,NO表示失败
     */
    +(BOOL)keyedArchiver:(id)obj key:(NSString *)key
    {
        return [self keyedArchiver:obj key:key path:DefaultKeyedArchiverPath];
    }
    
    /**
     *  归档
     *
     *  @param obj  须要归档的类
     *  @param key  归档key
     *  @param path 归档路劲
     *
     *  @return YES表示归档成功,NO表示归档失败
     */
    +(BOOL)keyedArchiver:(id)obj key:(NSString *)key path:(NSString *)path
    {
        NSMutableData *tpData = [NSMutableData data];
        NSKeyedArchiver *keyedArchiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:tpData];
        [keyedArchiver encodeObject:obj forKey:key];
        [keyedArchiver finishEncoding];
        return [tpData writeToFile:path atomically:YES];
    }
    
    /**
     *  解档
     *
     *  @param key key
     *
     *  @return 解析的结果
     */
    +(id)keyedUnarchiver:(NSString *)key
    {
        return [self keyedUnarchiver:key path:DefaultKeyedArchiverPath];
    }
    
    /**
     *  解档
     *
     *  @param key  解挡key
     *  @param path 解挡路径
     *
     *  @return 解析的结果
     */
    +(id)keyedUnarchiver:(NSString *)key path:(NSString *)path
    {
        NSMutableData *tpData = [NSMutableData dataWithContentsOfFile:path];
        NSKeyedUnarchiver *keyedUnarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:tpData];
        return [keyedUnarchiver decodeObjectForKey:key];
    }
    
    @end
    
  • 相关阅读:
    20155219 2017-2018-1 《信息安全系统设计》第4周学习总结
    20155219 2017-2018-1 《信息安全系统设计》第3周学习总结
    20155219实践题目实现od命令
    20155219 2017-2018-1 《信息安全系统设计》第4周课堂实践
    2017-2018-1 20155219《信息安全系统设计基础》第1周学习总结
    课堂实践6-7
    20155219 实验五《网络编程与安全》实验报告
    20155219 2016-2017-2《Java程序设计》课程总结
    20155212 mybash的实现
    20155212 2017-2018-1 《信息安全系统设计》第5周学习总结
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/6937899.html
Copyright © 2011-2022 走看看