很多时候我们都是会定义自己项目的模型,有些需要缓存本地,归档的话就得重写NSCoding 协议,但是每个模型类都去写的话就会非常的繁琐,而且会做很多重复的工作,代码都是一样的,只是名字不一样而已。

那有没有通用的方法呢?能不能只写一套代码完成呢?

答案是:有的

我们利用 runtime 机制可以做到

直接上代码:


1、导入头文件

#import <objc/runtime.h>

2、定义通用宏:

#define PXYNSCodingRuntime_EncodeWithCoder(Class) \
    unsigned int outCount = 0;\
    Ivar *ivars = class_copyIvarList([Class class], &outCount);\
    for (int i = 0; i < outCount; i++) {\
        Ivar ivar = ivars[i];\
        NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)];\
        [aCoder encodeObject:[self valueForKey:key] forKey:key];\
    }\
    free(ivars);
#define PXYNSCodingRuntime_InitWithCoder(Class)\
    if (self = [super init]) {\
        unsigned int outCount = 0;\
        Ivar *ivars = class_copyIvarList([Class class], &outCount);\
        for (int i = 0; i < outCount; i++) {\
            Ivar ivar = ivars[i];\
            NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)];\
            id value = [aDecoder decodeObjectForKey:key];\
            if (value) {\
                [self setValue:value forKey:key];\
            }\
        }\
        free(ivars);\
    }\
    return self;

3、实际调用:

@implementation Common

- (void)encodeWithCoder:(NSCoder *)aCoder {
    PXYNSCodingRuntime_EncodeWithCoder(self)
}
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
    PXYNSCodingRuntime_InitWithCoder(self)
}
@end