Last active
August 29, 2015 14:20
-
-
Save wangmingfu/6f42ad9618e092c391d6 to your computer and use it in GitHub Desktop.
实体序列化
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
+ (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