请选择 进入手机版 | 继续访问电脑版
源码天堂 设为首页 收藏本站
开启辅助访问 切换到宽版

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

切换风格 立即注册 找回密码

IOS教程网

新浪微博达人勋

2441

积分

273

金钱

0

广播

Rank: 6Rank: 6

积分
2441

活跃会员热心会员推广达人社区QQ达人最佳新人

发表于 2018-1-9 15:34:27 | 显示全部楼层 |阅读模式
分享到:
为什么要有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;
                 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;
                 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调用上述两个函数得到其返回结果再分别依次遍历输出其返回值
979044-20180105133820909-807459561.jpg

执行上述测试函数后在控制台输出结果为:
             Center.jpg
从上述执行结果可以很好的说明前者只获取由@property声明的属性,而后者不但获取了@property属性,而且还获取了@interface大括号中声明的变量


新浪微博达人勋

410

积分

6

金钱

0

广播

Rank: 3Rank: 3

积分
410
发表于 2018-1-9 15:37:20 | 显示全部楼层
前排顶,很好!

新浪微博达人勋

2437

积分

271

金钱

0

广播

Rank: 6Rank: 6

积分
2437

社区QQ达人最佳新人

发表于 2018-1-30 14:36:39 | 显示全部楼层
支持楼主,用户楼主,楼主英明呀!!!
您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

本版积分规则

小黑屋|手机版|Archiver|IOS教程网. ( 粤ICP备12089784号  

GMT+8, 2018-2-24 14:24 , Processed in 0.186033 second(s), 41 queries .

Powered by Discuz X3.1

© 2001-2013 IOS教程网

快速回复 返回顶部 返回列表