• 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大括号中声明的变量

  • 相关阅读:
    进程和线程
    VC中使对话框全屏的方法
    初为项目经理
    Sqlite知识小记
    ERROR L105: PUBLIC REFERS TO IGNORED SEGMENT
    RTX51.LIB NOT FOUND
    Virtual Villagers 攻略
    专业术语常用名词缩写中英文对照
    Eric的四个无刷新(异步更新)示例
    ASP.NET 安全认证(一)—— 如何运用 Form 表单认证 .
  • 原文地址:https://www.cnblogs.com/jingxin1992/p/8204018.html
Copyright © 2020-2023  润新知