• Runtime应用(三)实现NSCoding的自动归档和自动解档


    当我们需要将一个对象进行归档时,都要让该对象的类遵守NSCoding协议,再实现归档和接档方法。例如有一个Person类,该类有两个成员变量

    @property (nonatomic,copy) NSString *name;
    @property (nonatomic,assign) int age;
    

    两个协议的实现方法如下

    /**
     *  将对象写入某个文件时需要调用,在该方法中说明哪些属性需要存储
     */
    - (void)encodeWithCoder:(NSCoder *)encoder
    {
        [encoder encodeObject:self.name forKey:@"name"];
        [encoder encodeInt:self.age forKey:@"age"];
    }
    
    
    /**
     *  从文件中解析对象时会调用,在该方法中解析对象的属性
     */
    - (id)initWithCoder:(NSCoder *)decoder
    {
        if (self = [super init]) {
            // 解析之后要赋值给属性
            _name = [decoder decodeObjectForKey:@"name"];
            _age = [decoder decodeIntForKey:@"age"];
        }
        return self;
    }

    但当该类拥有上百个属性时,那将会花费更多的功夫在重复代码上,所以使用运行时机制截取类的成员变量,进行赋值

    例如有一个狗类Dog和它的父类动物类Animal

    狗类的成员变量有

    @property (nonatomic,copy) NSString *name;
    @property (nonatomic,assign) int age;

    动物类的成员变量有

    @property (nonatomic,assign) double weight;

    当我们需要将狗对象进行归档时,可以在类中这样重写归档和解档方法

    - (id)initWithCoder:(NSCoder *)aDecoder
    {
       
        if (self = [super init]) {
            Class c = self.class;
            // 截取类和父类的成员变量
            while (c && c != [NSObject class]) {
                unsigned int count = 0;
                Ivar *ivars = class_copyIvarList(c, &count);
                for (int i = 0; i < count; i++) {
                   
                    NSString *key = [NSString stringWithUTF8String:ivar_getName(ivars[i])];
                   
                    id value = [aDecoder decodeObjectForKey:key];
                   
                    [self setValue:value forKey:key];
    
                }
                // 获得c的父类
                c = [c superclass];
                free(ivar);
            }
           
           
        }
        return self;
    }
    
    - (void)encodeWithCoder:(NSCoder *)aCoder
    {
       
         Class c = self.class;
        // 截取类和父类的成员变量
        while (c && c != [NSObject class]) {
            unsigned int count = 0;
           
            Ivar *ivars = class_copyIvarList(c, &count);
           
            for (int i = 0; i < count; i++) {
                Ivar ivar = ivars[i];
                NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)];
    
                id value = [self valueForKey:key];
               
                [aCoder encodeObject:value forKey:key];
            }
            c = [c superclass];
            // 释放内存
            free(ivar);
        }
       
    }

     代码测试:

    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        CXDog *d = [[CXDogalloc] init];
        d.name = @"cx";
        d.age = 12;
        d.weight = 1.55;
        // 将对象归档
        [NSKeyedArchiverarchiveRootObject:d toFile:@"/Users/c_xie/Desktop/wj.xxoo"];
        // 将对象解档
        CXDog *dog = [NSKeyedUnarchiverunarchiveObjectWithFile:@"/Users/c_xie/Desktop/wj.xxoo"];
        NSLog(@"%@,%d,%f",dog.name,dog.age,d.weight);
       
    }

    以后就算有再多的属性,一个循环搞定

  • 相关阅读:
    文本编辑器js插件
    日期时间JS插件
    原生JS写验证码
    PHP语言开发微信公众平台(订阅号)之curl命令
    PHP语言开发微信公众平台(订阅号)之开启开发者模式(3)
    PHP语言开发微信公众平台(订阅号)之注册(1)
    取出关联数组的key值和values值
    关于PHP单双引号解析变量的问题
    HDU1243:反恐训练营
    HDU1244:Max Sum Plus Plus Plus
  • 原文地址:https://www.cnblogs.com/junhuawang/p/5798827.html
Copyright © 2020-2023  润新知