zoukankan      html  css  js  c++  java
  • iOS 固化

    在 iOS 中,有很多途径可以将对象写入磁盘,其中最重要的一种途径是“固化”(archiving):固化是将单个或多个对象从内存写入文件系统的过程。“解固”(unarchiving)是从文件读取对象并写回内存。

    固化可以通过 NSCoder 实例来完成, NSCoder 实例本身就是一个数据容器,可以存放对象和对象的数据,一旦 NSCoder 收集齐所需的数据,就可以将其写入指定的文件系统中的文件。

    不是所有对象都可以固化 - 只有遵守 NSCoding 协议的对象才可以。

    NSCoding 协议有两个方法(都是必须的方法):encodeWithCoder:(固化用);initWithCoder(解固用)

    一, 对象的固化

    通过 NSKeyedArchiver 的类方法 archiveRootObject:toFile :可以将遵守 NSCoding 协议的对象写入文件。NSKeyedArchiver 是 NSCoder 的子类。

    archiveRootObject:toFile: 方法的第一个参数是根对象(root Object);第二个参数是写入文件的路径

    // 将传入的文件名加在目录后并返回
    // archiverRootObject:toFile:方法会创建一个 NSKeyedArchiver 实例,然后向 allObjects  发送 encodeWithCoder 消息,并将新创建的 NSKeyedArchiver 对象作为参数传入。 固化数组时,数组中的对象也会被固化(前提是这些对象也遵守 NSCoding 协议)
     return [NSKeyedArchiver archiveRootObject:allObjects toFile:objectsPath]; 

    如图:

    在 encodeWithCoder 中,通过向 NSCoder 对象(这里是 NSKeyedArchiver 对象)发送 encodeObject:forkey: 消息,可以对对象的实例变量编码(encode)

    - (void)encodeWithCoder:(NSCoder *)encoder
    {
      // 根据变量名固化实例变量
      // 如果实例变量是对象,则该对象也会受到 encodeWithCoder: 消息
      [encoder encodeObject:objectName1 forkey:@"objectName1"];
      [encoder encodeObject:objectName2 forkey:@"objectName2"] 
      // 基本类型
      [encode encodeInt:int1 forkey:@"int1"];          
    }

    这类固化称为“有键固化”(keyed archiving),有键固化的工作机制与  NSMutableDictionary 非常类似:通过加入对象,并用同一个键取出对象,有键固化使用的键都是 NSString 实例,通常是需要编码的实例变量的变量名

    如果传入 encodeWithCoder: 的实例对象是对象,那么该对象也会受到 encodeWithCoder:消息,所以固化是一个递归过程

    二, 对象的解固

    应用通过“解固”来载入固化后的对象,首先,程序会创建一个 NSCoder 实例,然后从文件系统读入数据,最后解固固化后的对象。

    通过 NSKeyedUnarchiver 的类方法 unarchiveObjectWithFile: 可将数据从文件系统还原至内存。

    NSKeyedUnarchiver 也是 NSCoder 的子类。 unarchiveObjectWithFile: 的参数是固化文件的路径,它会将相应的文件读入内存,然后开始一系列的解固过程

    // 如果allObjects数组不存在,则从文件取之
    // 注意,unarchiveObjectWithFile: 的返回值类型为 id
    if(!allObjects)
    {
      NSString *path= obejctsPath;
      allObjects = [[NSKeyedUnarchiver unarchiveObjectWithFile:path] retain];    
    }

    解固的根对象为 allObjects ,类型为NSMutaleArray,NSMutableArray 的 initWithCoder: 方法会向每个已固化对象发送 decodeObjectForKey: 消息,从而解码数组中的内容

    - (id)initWithCoder:(NSCoder *)decoder
    {
      self = [super init];
      if (self) {
         [self setObjectName1:[decoder decodeObjectForKey:@"objectName1"]];
          [self setObjectName2:[decoder decodeObjectForKey:@"objectName2"]];
          [self setint1:[decoder decodeIntForKey:@"int1"]] ; 
        }
          return self ;  
    }    

  • 相关阅读:
    命令行环境下简单实用的工具——重定向&管道
    阿里2014校招笔试题(南大)——利用thread和sleep生成字符串的伪随机序列
    Pooled Allocation(池式分配)实例——Keil 内存管理
    modelsim数据导出用于matlab绘图
    顺序块和并行块
    初入博园
    数字图像处理实验(7):PROJECT 04-03 , Lowpass Filtering 标签: 图像处理MATLAB 2017-05-25 09:30 109人
    杭电acm刷题(3):1062,Text Reverse 标签: 杭电acm 2017-05-15 08:26 126人阅读 评论(0)
    杭电ACM刷题(2):1005,Number Sequence 标签: 杭电acmC语言 2017-05-11 22:43 116人阅读
    数字图像处理实验(6):PROJECT 04-02,Fourier Spectrum and Average Value 标签: 图像处理MATLABfft 2017-05-07 23:1
  • 原文地址:https://www.cnblogs.com/dayw/p/3270334.html
Copyright © 2011-2022 走看看