• 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 ;  
    }    

  • 相关阅读:
    Access的相关SQL语句
    决心创业
    [转]在.NET环境中使用单元测试工具NUnit
    [转]IE"单击以激活控件"网站代码解决法
    [转]C#中ToString格式大全
    [转]div中放flash运行30秒钟后自动隐藏效果
    Property和attribute的区别
    C++中的虚函数(virtual function)
    进程间通信方式
    关于页面传值的方法
  • 原文地址:https://www.cnblogs.com/dayw/p/3270334.html
Copyright © 2020-2023  润新知