runtime运行时之自动归档(一)

开发中少不了用到NSKeyedArchiver归档和解档,之前我是这么写的:

//NSCoding实现
- (void)encodeWithCoder:(NSCoder *)aCoder{
    [aCoder encodeObject:self.name forKey:@"name"];
    [aCoder encodeObject:self.ID forKey:@"ID"];
}

- (id)initWithCoder:(NSCoder *)aDecoder{
    if (self = [super init]) {
        self.ID = [aDecoder decodeObjectForKey:@"ID"];
        self.name = [aDecoder decodeObjectForKey:@"name"];
    }
    return self;
}

这样写很传统,但是如果遇到了归档100个属性呢?那不是完蛋了!?
自此出现这个问题之后,接触到了runtime中的Ivar,如下:

typedef struct objc_ivar *Ivar;

可见它是一个结构体指针,它定义对象的实例变量,包括类型和名字。包括@interface大括号中的属性和@property中的属性。这也就是它与objc_property_t的区别。
中声明了

OBJC_EXPORT Ivar *class_copyIvarList(Class cls, unsigned int *outCount) 

#######这个方法就是copy cls类中@interface中的成员变量和属性,将数量回传给outCount,返回值我们看到了,就是这个Ivar,是个结构体指针,指向了第一个属性结构体的首地址。
#######之后我们利用返回的ivars指针,配合ivar_getname()方法去除字符串形式的变量名称转换成NSString作为key,便可以进行后续操作了
由于是copy操作,后续不要忘记free()释放内存。

我们用运行时的方法实现无论多少属性都通用的归档方法:

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    self = [super init];
    if (self) {
        unsigned int count = 0;
        Ivar *ivars = class_copyIvarList([self class], &count);
        for (int i = 0; i < count; i++) {
            NSString *key = [NSString stringWithUTF8String:ivar_getName(ivars[i])];
            [self setValue:[aDecoder decodeObjectForKey:key] forKey:key];
        }
        free(ivars);
    }
    return self;
}

- (void)encodeWithCoder:(NSCoder *)aCoder {
    unsigned int count = 0;
    Ivar *ivars = class_copyIvarList([self class], &count);
    for (int i = 0; i < count; i++) {
        NSString *key = [NSString stringWithUTF8String:ivar_getName(ivars[i])];
        [aCoder encodeObject:[self valueForKey:key] forKey:key];
    }
    free(ivars);
}
runtime在实际当中还有很多的应用,之后会慢慢的一一介绍,也算是本人的一个爱好吧,希望读者看到之后点个赞鼓励下,多交流,多指点!

你可能感兴趣的:(runtime运行时之自动归档(一))