标签:
使用过一段时间后,发现当模型改动,版本升级时不太方便。
前段时间因为写了段自动序列化的代码,分记录下:
原理就是一个根类通过条件反射实现所有数据成员的序列化,其它数据模型继承自它即可
解码实现
-(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 NSLog for (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])];//变量名字 key if ([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
标签:
原文地址:http://www.cnblogs.com/onlywish/p/4189015.html