使用过一段时间后,发现当模型改动,版本升级时不太方便。
前段时间因为写了段自动序列化的代码,分记录下:
原理就是一个根类通过条件反射实现所有数据成员的序列化,其它数据模型继承自它即可解码实现
-(id)initWithCoder:(NSCoder *)aDecoder{self = [super init];if (self) {id tempClass = [self class];while (tempClass != [NSObject class]) {unsigned int outCount;Ivar * ivars = class_copyIvarList(tempClass, &outCount);for (int i = 0; i < outCount; i++) { //ivars如果是NULL outCount = 0,这里就判断了const char * typeEncode = ivar_getTypeEncoding(ivars[i]); //变量的类型void * data = (char *)self + ivar_getOffset(ivars[i]); //变量的内存地址NSString * name = [NSString stringWithUTF8String:ivar_getName(ivars[i])];//key值if ([self isSaveToDriver:name]) {switch (typeEncode[0]) {case ‘i’:case ‘I’://整型跟无符号整型*(int *)data = [aDecoder decodeIntForKey:name];break;case ‘B’://bool型*(BOOL *)data = [aDecoder decodeBoolForKey:name];break;case ‘c’://字符型*(char *)data = *[aDecoder decodeBytesForKey:name returnedLength:NULL];break;case ‘f’://float*(float *)data = [aDecoder decodeFloatForKey:name];break;case ‘d’://double*(double *)data = [aDecoder decodeDoubleForKey:name];break;case ‘@’://object*(id *)data = [[aDecoder decodeObjectForKey:name] retain];break;case ‘{‘://结构体{NSUInteger sizep;const unsigned char * _data = [aDecoder decodeBytesForKey:name returnedLength:&sizep];memcpy(data, _data, sizep);}break;default:@throw[NSException exceptionWithName:@"编码异常" reason:[NSString stringWithFormat:@"有一个对象没有实例化,对象类型%s,所在类%@,变量名%@",typeEncode,NSStringFromClass(tempClass),name] userInfo:nil];break;}}// NSLog(@"ivar name = %s type = %s",ivar_getName(ivars[i]),ivar_getTypeEncoding(ivars[i]));}tempClass = [tempClass superclass];free(ivars);//释放ivarlist}}return self;}[/cpp]编码实现[cpp]-(void)encodeWithCoder:(NSCoder *)aCoder{id tempClass = [self class];while (tempClass != [NSObject class]) {unsigned int outCount;Ivar * ivars = class_copyIvarList(tempClass, &outCount);#undef NSLogfor (int i = 0; i < outCount; i++) {const char * typeEncode = ivar_getTypeEncoding(ivars[i]); //变量类型void * data = (char *)self + ivar_getOffset(ivars[i]); //变量地址NSString * name = [NSString stringWithUTF8String:ivar_getName(ivars[i])];//变量名字 keyif ([self isSaveToDriver:name]) {switch (typeEncode[0]) {case ‘i’:case ‘I’://整型跟无符号整型[aCoder encodeInt:*(int *)data forKey:name];break;case ‘B’:NSLog(@"%x",(int)data);[aCoder encodeBool:*(BOOL *)data forKey:name];break;case ‘c’://字符型[aCoder encodeBytes:data length:1 forKey:name];break;case ‘f’://float[aCoder encodeFloat:*(float *)data forKey:name];break;case ‘d’://double[aCoder encodeDouble:*(double *)data forKey:name];break;case ‘@’://object[aCoder encodeObject:*(NSObject **)data forKey:name];break;case ‘{‘://结构体{NSUInteger sizep = 0;NSUInteger alignment = 0;NSGetSizeAndAlignment(typeEncode, &sizep, &alignment);[aCoder encodeBytes:data length:sizep forKey:name];}break;default:{@throw[NSException exceptionWithName:@"编码异常" reason:[NSString stringWithFormat:@"有一个对象没有编码,对象类型%s,所在类%@,变量名%@",typeEncode,NSStringFromClass(tempClass),name] userInfo:nil];}break;}}}tempClass = [tempClass superclass];free(ivars);}}
把这两个函数复制到根类即可实现自动序列化
源博客地址,http://onlywish.me