• 使用runtime完成解档归档


    简单的创建一个Person对象,并声明几个属性

    @interface Person : NSObject<NSCoding> // 归档问题 必须遵守该协议
    /**  */
    @property(copy,nonatomic)NSString * name;
    /**  */
    @property(assign,nonatomic)int age;
    @property(assign,nonatomic)int age1;
    @end

    设置哪些属性是需要归档的

    //告诉系统,归档哪些属性
    - (void)encodeWithCoder:(NSCoder *)coder
    {
        //利用runtime 来归档!!
        unsigned int count = 0;
        
        // 拷贝一个类 的属性列表
        Ivar * ivars = class_copyIvarList([Person class], &count); // 在C语言中 但凡看到了一个传递了基本数据类型的指针 一般都是在函数中 改变外面参数的值 (这个ivars 可以形象的比喻为 数组 但是又区别于数组 如当我们 做ivars[100] 有可能不会报我们常见的数组越界而返回一个null  所以你懂得)
        
        for (int i = 0; i < count; i++) {
            //拿出每一个Ivar
            Ivar ivar = ivars[i];
            const char * name = ivar_getName(ivar); // 将属性转行成字符串
            NSString * KEY = [NSString stringWithUTF8String:name];
            //归档
            [coder encodeObject:[self valueForKey:KEY] forKey:KEY]; // 通过KVC 来拿到当前类 的属性
        }
        
        //C语言里面!! 一旦遇到了copy creat new 需要释放 (否则 我们归档一次  内存泄漏一次 导致内存暴增)
        free(ivars);
        
    }

    设置哪些属性需要解档

    - (instancetype)initWithCoder:(NSCoder *)coder
    {
        self = [super init];
        if (self) {
            unsigned int count = 0;
            Ivar * ivars = class_copyIvarList([Person class], &count);
            for (int i = 0; i < count; i++) {
                Ivar ivar = ivars[i];
                const char * name = ivar_getName(ivar);
                NSString * KEY = [NSString stringWithUTF8String:name];
                //解档
                id value = [coder decodeObjectForKey:KEY];
                //通过KVC 设置
                [self setValue:value forKey:KEY]; // 通过KVC 将拿到的 值 设置给当前类 的 属性
            }
            
            free(ivars); // 释放内存 
        }
        return self;
    }

    使用

      

    - (IBAction)save:(id)sender {
        //创建一个对象
        Person * p = [[Person alloc]init];
        p.name = @"hank";
        p.age = 18;
        p.age1 = 18;
        
        NSString * tmpPath = NSTemporaryDirectory(); // 这里我们暂且放在 temp 路径里
        NSString * filePath = [tmpPath stringByAppendingPathComponent:@"hank.hank"];
        
        
        //归档!!
        [NSKeyedArchiver archiveRootObject:p toFile:filePath];
        
        
    }
    - (IBAction)read:(id)sender {
        //路径
        NSString * tmpPath = NSTemporaryDirectory();
        NSString * filePath = [tmpPath stringByAppendingPathComponent:@"hank.hank"];
        
        //解档
        Person * p = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
        NSLog(@"%@老师今年%d岁了!真实年龄是:%d",p.name,p.age,p.age1);
        
    }

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

    by:ml

  • 相关阅读:
    【转】ON_COMMAND ON_MESSAGE ON_NOTIFY区别与联系
    Eureka
    application.yml-mysql8
    sprigcloud
    springboot
    maven
    排序算法之基数排序
    排序算法之桶排序
    排序算法之计数排序
    排序算法之堆排序
  • 原文地址:https://www.cnblogs.com/widgetbox/p/11434856.html
Copyright © 2020-2023  润新知