zoukankan      html  css  js  c++  java
  • Runtime之NSCoding的自动归档、接档

     为什么要有Runtime的NSCoding的自动归档、接档

    大家所熟知的方法

    //归档方法

    - (void)encodeWithCoder:(NSCoder *)aCoder

    {

        //当学生被归档,学生要将成员都归档

             [aCoder encodeObject:self.name forKey:@"name"];

             [aCoder encodeInteger:self.age forKey:@"age"];

    }

    //解归档方法

    - (id)initWithCoder:(NSCoder *)aDecoder

    {

              if (self = [super init]) {

                      //当学生被解归档,学生要将成员都解归档

                      self.name = [aDecoder decodeObjectForKey:@"name"];

                      self.age = [aDecoder decodeIntegerForKey:@"age"];

               }

              return self;

    }

    这是因为数据少的情况下,如果数据有几十条呢?写几十行这种代码,你感觉怎么样?只要错一个字节,你这个数据就是没有的。

    这就出现了Runtime的自动归档、接档。

    Runtime有一个方法可以获取当前类里面的属性列表,既然成员变量都能拿到,每一个成员变量所对应的key以及value当然也可以拿到,这样就不需要自己一行一行的去归档,接档了。

    #import "person.h" 

    @implementation person

    // 接档读数据

    - (instancetype)initWithCoder:(NSCoder *)aDecoder {

                 if (self = [super init])  {

               /*

                  OBJC_EXPORT Ivar *class_copyIvarList(Class cls, unsigned int *outCount)

                  Class cls 表示获取那一个类的属性列表

                   unsigned int *outCount 用于存储获取到属性个数

              */

              unsigned int count = 0;

              Ivar *ivar = class_copyIvarList([self class], &count);

             for (int i = 0; i < count; i++) {

                    //根据每一个属性取出对应的key 注意key值是c语言的key

                     Ivar iva = ivar[i];

                     const charchar *key = ivar_getName(iva);

                     // 转换为oc 

                     NSString *strName = [NSString stringWithUTF8String:key]; 

                     //进行解档取值

                    id value = [aDecoder decodeObjectForKey:strName];

                    //利用KVC对属性赋值

                     [self setValue:value forKey:strName];

              }

              free(ivar);

       }

    return self;

    }

    // 归档存数据

    - (void)encodeWithCoder:(NSCoder *)aCoder {

             unsigned int count;

             Ivar *ivar = class_copyIvarList([self class], &count);

             for (int i=0; i < count; i++) {

                     Ivar iv = ivar[i];

                     const charchar *name = ivar_getName(iv);

                     NSString *strName = [NSString stringWithUTF8String:name];

                    //利用KVC取值

                    id value = [self valueForKey:strName];

                    [aCoder encodeObject:value forKey:strName];

             }

               free(ivar);

    }

    需要注意的一个细节就是当涉及到Runtime的时候。一定要记得内存的释放。Xcode的ARC只适用于OC,对于C的指针,要记得手动free。

    另外补充一下class_copyPropertyList和class_copyIvarList的区别:

    class_copyPropertyList返回的仅仅是对象类的属性(@property申明的属性),而class_copyIvarList返回类的所有属性和变量(包括在@interface大括号中声明的变量),下面做个简单的测试。首先,定义一个WFrequencyManager类,然后在测试类中写一个测试函数testProperties调用上述两个函数得到其返回结果再分别依次遍历输出其返回值

    执行上述测试函数后在控制台输出结果为:
                 

     从上述执行结果可以很好的说明前者只获取由@property声明的属性,而后者不但获取了@property属性,而且还获取了@interface大括号中声明的变量

  • 相关阅读:
    GTK+ 3.6.2 发布,小的 bug 修复版本
    RunJS 新增 Echo Ajax 测试功能
    Mozilla 发布 Popcorn Maker,在线创作视频
    Sina微博OAuth2框架解密
    Mina状态机State Machine
    Mozilla 发布 Shumway —— 纯JS的SWF解析器
    Code Browser 4.5 发布,代码浏览器
    ROSA 2012 "Enterprise Linux Server" 发布
    ltrace 0.7.0 发布,程序调试工具
    Artifactory 2.6.5 发布,Maven 扩展工具
  • 原文地址:https://www.cnblogs.com/FZP5/p/8204711.html
Copyright © 2011-2022 走看看