iOS 利用runtime实现model类型的归档解档

需求分析:在日常开发中,如果我们需要对model数据进行本地存储时,我们都知道,model对象不能直接存入沙盒,我们需要实现NSCoding协议,将对象转化为NSData类型后再进行存储。当我们需要数据时,先取出NSData数据,在转化为model对象来使用。这样我们会遇到一个问题,因为我们需要把model的每一个属性进行encode和decode,这样如果model的属性很少,还好说,如果很多,我们会浪费很多代码。此时,我们可以利用runtime来实现这个功能。原理是通过runtime我们可以在initWithCoder:以及encoderWithCoder:中遍历类的所有变量,取得变量名作为KEY值,最后使用KVC强制取得或者赋值给对象。
代码如下:

- (instancetype)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(ivars);
        }
    }
    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(ivars);
    }
}

这样就算model有再多属性我们也不会感到头疼了。记得导入#import <objc/runtime.h>头文件。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容