Skip to content

Instantly share code, notes, and snippets.

@wangmingfu
Last active August 29, 2015 14:20
Show Gist options
  • Save wangmingfu/6f42ad9618e092c391d6 to your computer and use it in GitHub Desktop.
Save wangmingfu/6f42ad9618e092c391d6 to your computer and use it in GitHub Desktop.
实体序列化
+ (NSData *)jsonDataFromObject:(id)object;
{
static Class NSObjectClass;
static NSCharacterSet *ClassRestrictiveCharacterSet;
if( !NSObjectClass )
{
NSObjectClass = [NSObject class];
ClassRestrictiveCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@" @\""];
}
NSMutableDictionary *kvpDict = [[NSMutableDictionary alloc] init];
Class classItr = [object class];
while( classItr && ( classItr != NSObjectClass ) )
{
unsigned int propertyCount = 0;
objc_property_t *properties = class_copyPropertyList( classItr, &propertyCount );
for( unsigned int ii = 0; ii < propertyCount; ++ii )
{
objc_property_t property = properties[ ii ];
NSString *propertyName = @( property_getName( property ) );
const char *backingIvarName = property_copyAttributeValue( property, "V" );
Ivar ivar = class_getInstanceVariable( classItr, backingIvarName );
id value = nil;
NSString *propertyTypeName = @( property_copyAttributeValue( property, "T" ) );
switch( [propertyTypeName characterAtIndex:0] )
{
case _C_ID:
propertyTypeName = [propertyTypeName stringByTrimmingCharactersInSet:ClassRestrictiveCharacterSet];
if( [propertyTypeName isEqualToString:@"NSString"]
|| [propertyTypeName isEqualToString:@"NSNumber"]
|| [propertyTypeName isEqualToString:@"NSArray"]
|| [propertyTypeName isEqualToString:@"NSDictionary"]
|| [propertyTypeName isEqualToString:@"NSNull"])
{
value = [object valueForKey:propertyName];
}
else if( [propertyTypeName isEqualToString:@"NSData"] )
{
NSData *dataValue = [object valueForKey:propertyName];
value = [[NSString alloc] initWithData:dataValue encoding:NSUTF8StringEncoding];
}
else if( [propertyTypeName isEqualToString:@"NSURL"] )
{
NSURL *urlValue = [object valueForKey:propertyName];
value = [urlValue absoluteString];
}
break;
case _C_CHR:
{
char charValue = *( (char*)( (__bridge void*)object + ivar_getOffset( ivar ) ) );
value = [NSNumber numberWithChar:charValue];
}
break;
case _C_UCHR:
{
unsigned char unsignedCharValue = *( (unsigned char*)( (__bridge void*)object + ivar_getOffset( ivar ) ) );
value = [NSNumber numberWithUnsignedChar:unsignedCharValue];
}
break;
case _C_SHT:
{
short shortValue = *( (short*)( (__bridge void*)object + ivar_getOffset( ivar ) ) );
value = [NSNumber numberWithShort:shortValue];
}
break;
case _C_USHT:
{
unsigned char unsignedShortValue = *( (unsigned short*)( (__bridge void*)object + ivar_getOffset( ivar ) ) );
value = [NSNumber numberWithUnsignedShort:unsignedShortValue];
}
break;
case _C_INT:
{
int intValue = *( (int*)( (__bridge void*)object + ivar_getOffset( ivar ) ) );
value = [NSNumber numberWithInteger:intValue];
}
break;
case _C_UINT:
{
unsigned int unsignedIntValue = *( (unsigned int*)( (__bridge void*)object + ivar_getOffset( ivar ) ) );
value = [NSNumber numberWithUnsignedInteger:unsignedIntValue];
}
break;
case _C_LNG:
{
long longValue = *( (long*)( (__bridge void*)object + ivar_getOffset( ivar ) ) );
value = [NSNumber numberWithLong:longValue];
}
break;
case _C_ULNG:
{
unsigned long unsignedLongValue = *( (unsigned long*)( (__bridge void*)object + ivar_getOffset( ivar ) ) );
value = [NSNumber numberWithUnsignedLong:unsignedLongValue];
}
break;
case _C_LNG_LNG:
{
long long longLongValue = *( (long long*)( (__bridge void*)object + ivar_getOffset( ivar ) ) );
value = [NSNumber numberWithLongLong:longLongValue];
}
break;
case _C_ULNG_LNG:
{
unsigned long long unsignedLongLongValue = *( (unsigned long long*)( (__bridge void*)object + ivar_getOffset( ivar ) ) );
value = [NSNumber numberWithUnsignedLongLong:unsignedLongLongValue];
}
break;
case _C_FLT:
{
float floatValue = *( (float*)( (__bridge void*)object + ivar_getOffset( ivar ) ) );
value = [NSNumber numberWithFloat:floatValue];
}
break;
case _C_DBL:
{
double doubleValue = *( (double*)( (__bridge void*)object + ivar_getOffset( ivar ) ) );
value = [NSNumber numberWithDouble:doubleValue];
}
break;
case _C_BOOL:
{
bool boolValue = *( (bool*)( (__bridge void*)object + ivar_getOffset( ivar ) ) );
value = [NSNumber numberWithBool:boolValue];
}
break;
}
if( value )
{
[kvpDict setObject:value forKey:propertyName];
}
}
classItr = class_getSuperclass( classItr );
}
NSError *error = nil;
return [NSJSONSerialization dataWithJSONObject:kvpDict options:0 error:&error];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment