一、简介
对于ios开发中会经常用到json,而且网上也会有许多第三方的库,例如:SONKit、SBJson、TouchJson等。
也有许多人对以上库做过一些性能测试,发现JSONKit非常高效而且易用,对比同类型的库有非常明显的性能优势,见下图:
所以本人也使用JSONKit来处理JSON数据。
二、JSONKit用法简介
上网搜一下"JSONKit用法”会有很多资料,所以我只是简单说一下和需要注意的地方。
JSONKit使用很简单,首先要引人JSONKit.h;经常使用的方法如下:
1.转换为JSON的方法
通常都是讲NSArray和NSDictionary转换为JSON,代码如下:
- (NSString *)sampleArrayTojson
{
//数组
NSArray *array = [[NSArray alloc] initWithObjects:@"a",@"b",@"c",nil];
NSString *json = [array JSONString];
NSLog(@"json = %@", [NSString stringWithString: json]);
[array release];
//json= ["a","b","c"]
return json;
}
- (NSString *)sampleDicTojson
{
//字典类型(对象)
NSArray *array1 = [NSArray arrayWithObjects:@"任何",@"中国",nil];
NSArray *array2 = [NSArray arrayWithObjects:[NSNumber numberWithBool:YES],[NSNumber numberWithInt:30],nil];
NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:array1,@"x",array2,@"y",nil];
NSString *json = [dic JSONString];
NSLog(@"json = %@", [NSString stringWithString: json]);
return json;
}
2.JSON转换为NSArray和NSDictionary
- (NSArray *)sampleJsonToArray
{
JSONDecoder *jd=[[JSONDecoder alloc] init];
NSString *json = [self sampleArrayTojson];
NSArray *array = [jd objectWithUTF8String:(const unsigned char *)[json UTF8String] length: (unsigned int)strlen([json UTF8String])];
for (NSString *string in array)
{
NSLog(@"json 数组元素:%@",string);
}
[jd release];
return array;
}
- (NSDictionary *)sampleJsonToDictionary
{
JSONDecoder *jd=[[JSONDecoder alloc] init];
NSString *json = [self sampleDicTojson];
NSDictionary *dic = [jd objectWithUTF8String:(const unsigned char *)[json UTF8String] length: (unsigned int)strlen([json UTF8String])];
for (NSString *string in [dic allKeys])
{
NSLog(@"json 字典元素:key = %@,value = %@",string,[dic objectForKey:string]);
}
[jd release];
return dic;
}
一定要注意点是,其他人介绍的在解析JSON时使用:
NSDictionary *ret2 = [jd objectWithUTF8String:(const unsigned char *)[json UTF8String] length:(unsigned int)[json length]];
上面的代码中,在计算字符串长度是使用了length方法;这个方法会有一些问题就是当json中有中文字符时就会有问题。所以一定要是使用strlen([json UTF8String])来计算长度。
JSONKit中只提供了NSArray和NSDictionary这样简单的对象转换为JSON,但是在实际的开放过程中我们经常需要将自定义的对象和JSON互转,所以下面是本人进行的一些扩展。
三、自定义对象和JSON的互转
在网上找到一些资料,就是JSONAutoSerializer个提供了自定义对象转换为JSON,就是先将对象转换为NSDictionary,后转换为JSON,但是仍然存在一些缺陷:
a.将对象转换为NSDictionary,而讲NSDictionary转换为JSON使用了其他的库,效率并不高。
b.这个类仅支持自定义类中属性为对象类型的类。
c.这个类并不支持讲JSON转换回对象。
针对以上几点,我做了一些优化。
1.将对象转换为JSON的代码如下:
- (NSString *)serializeObject:(id)theObject
{
NSString *className = NSStringFromClass([theObject class]);
const char *cClassName = [className UTF8String];
id theClass = objc_getClass(cClassName);
unsigned int outCount, i;
objc_property_t *properties = class_copyPropertyList(theClass, &outCount);
NSMutableArray *propertyNames = [[NSMutableArray alloc] initWithCapacity:1];
for (i = 0; i < outCount; i++)
{
objc_property_t property = properties[i];
NSString *propertyNameString = [[NSString alloc] initWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
[propertyNames addObject:propertyNameString];
[propertyNameString release];
}
NSMutableDictionary *finalDict = [[NSMutableDictionary alloc] initWithCapacity:1];
for(NSString *key in propertyNames)
{
// SEL selector = NSSelectorFromString(key);
// id value = [theObject performSelector:selector];
id value = [theObject valueForKey:key];//这是修改过的
if (value == nil)
{
value = [NSNull null];
}
[finalDict setObject:value forKey:key];
}
NSString *retString = [finalDict JSONString];
[propertyNames release];
[finalDict release];
return retString;
}
2.将转换后的JSON还原为对象
- (id)reverseJSON:(NSString *)jsonStr toClassObject:(Class)cClass;
{
JSONDecoder *jd = [[JSONDecoder alloc]init];
NSDictionary *retDic = [jd objectWithUTF8String:(const unsigned char *)[jsonStr UTF8String]
length:(unsigned int)strlen([jsonStr UTF8String])];
id resultObject = [[[cClass alloc] init] autorelease];
NSArray *keys = [retDic allKeys];
for (NSString *key in keys)
{
@try
{
[resultObject setValue:[retDic objectForKey:key]
forKey:[NSString stringWithFormat:@"%@",key]];
}
@catch (NSException *exception)
{
NSLog(@"%@",exception);
}
}
[jd release];
return resultObject;
}
这一部分是我自己写的,如果有什么问题可以留言,大家交流一下。