使用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

原文地址:https://www.cnblogs.com/widgetbox/p/11434856.html