网络接口协议 JSON 解析 Crash 的哪些事

我们在与服务器对接是常因为服务端修改和升级手机端出现Crash;一个好的容错机制是不应该出现Crash的;下在我们来看看常见的问题。

这是一个非常常用的JSON

这是对上面JSON解析的代码

如果服务端有一个接口不小心变成如下这样 (把code这个从字符串转成数字类型了),这个时候用上面的代码,你的客户端就会Crash;

面对上面的问题把代码完善一下

上面代码还是不够完善,我们再完善一下

这样问题是解决了,有没有办法无论服务器端给我们是字符串类型还是数字类型我们都兼容呢?代码设想如下:

在iOS里JSON解析过来有NSNull、NSString、NSNumber、NSArray、NSDictionary这几种类型;基础数据类型(NSNull、NSString、NSNumber)都放到NSArray和NSDictionary里;而NSString和NSNumber都有intValue这个方法;需要注意的是unsignedIntValue方法NSString是没有;所以我们要对NSString扩展保持NSNumber有的方法NSString也有;再对 NSArray扩展出intAtIndex;对
NSDictionary 扩展出 intForKey;代码如下:

NSString的扩展

#import <Foundation/Foundation.h>

@interface NSString (SHYUtil)

/*!
 @method charValue
 @abstract 把字符串转为char类型
 @result 返回char
 */
- (char)charValue;

/*!
 @method unsignedCharValue
 @abstract 把字符串转为unsigned char类型
 @result 返回unsigned char
 */
- (unsigned char)unsignedCharValue;

/*!
 @method shortValue
 @abstract 把字符串转为short类型
 @result 返回short
 */
- (short)shortValue;

/*!
 @method unsignedShortValue
 @abstract 把字符串转为unsigned short类型
 @result 返回unsigned short
 */
- (unsigned short)unsignedShortValue;

/*!
 @method unsignedIntValue
 @abstract 把字符串转为unsigned int类型
 @result 返回unsigned int
 */
- (unsigned int)unsignedIntValue;

/*!
 @method longValue
 @abstract 把字符串转为long类型
 @result 返回long
 */
- (long)longValue;

/*!
 @method unsignedLongValue
 @abstract 把字符串转为unsigned long类型
 @result 返回unsigned long
 */
- (unsigned long)unsignedLongValue;

/*!
 @method longLongValue
 @abstract 把字符串转为long long int类型
 @result 返回long long int
 */
- (long long int)longLongValue;

/*!
 @method unsignedLongLongValue
 @abstract 把字符串转为unsigned long long类型
 @result 返回unsigned long long
 */
- (unsigned long long)unsignedLongLongValue;

/*!
 @method unsignedIntegerValue
 @abstract 把字符串转为NSUInteger类型
 @result 返回NSUInteger
 */
- (NSUInteger)unsignedIntegerValue;

/*!
 @method numberValue
 @abstract 把字符串转为NSNumber类型
 @result 返回NSNumber
 */
- (NSNumber *)numberValue;

/*!
 @method arrayValue
 @abstract 把字符串转为NSArray类型
 @result 返回NSArray
 */
- (NSArray *)arrayValue;

/*!
 @method dictionaryValue
 @abstract 把字符串转为NSDictionary类型
 @result 返回NSDictionary
 */
- (NSDictionary *)dictionaryValue;

/*!
 @method dataValue
 @abstract 把字符串转为NSData类型,只支持UTF-8有损转换;排UTF-8编码的请用 dataUsingEncoding: 方法转
 @result 返回NSData
 */
- (NSData *)dataValue;

/*!
 @method decimalValue
 @abstract 把字符串转为NSDecimal类型
 @result 返回NSDecimal
 */
- (NSDecimal)decimalValue;

/*!
 @method decimalNumberValue
 @abstract 把字符串转为NSDecimalNumber类型
 @result 返回NSDecimalNumber
 */
- (NSDecimalNumber *)decimalNumberValue;

@end

#import "NSString+SHYUtil.h"
#import <CommonCrypto/CommonDigest.h>

#define SHY_CONVERT_USING(strtowhat) {    char buf[24];        if ([self getCString:buf maxLength:24 encoding:NSASCIIStringEncoding])         return strtowhat(buf, NULL, 10);    }     return strtowhat([self UTF8String], NULL, 10);

@implementation NSString (SHYUtil)

- (char)charValue
{
    const char *str = [self UTF8String];
    return str[0];
}

- (unsigned char)unsignedCharValue
{
    const char *str = [self UTF8String];
    return (unsigned char)str[0];
}

- (short)shortValue
{
    int i = [self intValue];
    return (short)i;
}

- (unsigned short)unsignedShortValue
{
    return (unsigned short)[self unsignedLongValue];
}

- (unsigned int)unsignedIntValue
{
    return (unsigned int)[self unsignedLongValue];
}

- (long)longValue
{
    SHY_CONVERT_USING(strtol);
}

- (unsigned long)unsignedLongValue
{
    SHY_CONVERT_USING(strtoul);
}

- (long long int)longLongValue
{
    SHY_CONVERT_USING(strtoll);
}

- (unsigned long long)unsignedLongLongValue
{
    SHY_CONVERT_USING(strtoull);
}

- (NSUInteger)unsignedIntegerValue
{
    return (NSUInteger)[self unsignedLongValue];
}

- (NSNumber *)numberValue
{
    NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
    return [formatter numberFromString:self];
}

- (NSArray *)arrayValue
{
    return [NSArray arrayWithObject:self];
}

- (NSDictionary *)dictionaryValue
{
    return [self propertyList];
}

- (NSData *)dataValue
{
    return [self dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
}

- (NSDecimal)decimalValue
{
    return [[NSDecimalNumber decimalNumberWithString:self] decimalValue];
}

- (NSDecimalNumber *)decimalNumberValue
{
    return [NSDecimalNumber decimalNumberWithString:self];
}

@end
NSArray的扩展
@interface NSArray (SHYUtil)

/*!
 @method anyObject
 @abstract 获取数组里的一个对象,索引号小的优先返回
 @result 返回数组里的一个对象
 */
- (id)anyObject;

/*!
 @method isEmpty
 @abstract 是否没有对象,没有对象也是为YES;
 @result 返回BOOL
 */
- (BOOL)isEmpty;

/*!
 @method objectAtIndexCheck:
 @abstract 检查是否越界和NSNull如果是返回nil
 @result 返回对象
 */
- (id)objectAtIndexCheck:(NSUInteger)index;

/*!
 @method objectAtIndexCheck:class:defaultValue:
 @abstract 获取指定index的对象并检查是否越界和NSNull如果是返回nil
 @param index 索引号
 @param aClass 检查类型
 @result 返回对象
 */
- (id)objectAtIndexCheck:(NSUInteger)index class:(__unsafe_unretained Class)aClass;

/*!
 @method objectAtIndexCheck:class:defaultValue:
 @abstract 获取指定index的对象并检查是否越界和NSNull如果是返回nil,获取失败返回为指定的defaultValue
 @param index 索引号
 @param aClass 检查类型
 @param defaultValue 获取失败要返回的值
 @result 返回对象,获取失败为指定的defaultValue
 */
- (id)objectAtIndexCheck:(NSUInteger)index class:(__unsafe_unretained Class)aClass defaultValue:(id)defaultValue;

/*!
 @method arrayAtIndex:
 @abstract 获取指定index的NSArray类型值
 @param index 索引号
 @result 返回NSArray,获取失败为nil
 */
- (NSArray *)arrayAtIndex:(NSUInteger)index;

/*!
 @method arrayAtIndex:defaultValue:
 @abstract 获取指定index的NSArray类型值
 @param index 索引号
 @param defaultValue 获取失败要返回的值
 @result 返回NSArray,获取失败为指定的defaultValue
 */
- (NSArray *)arrayAtIndex:(NSUInteger)index defaultValue:(NSArray *)defaultValue;

/*!
 @method mutableArrayAtIndex:
 @abstract 获取指定index的NSMutableArray类型值
 @param index 索引号
 @result 返回NSMutableArray,获取失败为nil
 */
- (NSMutableArray *)mutableArrayAtIndex:(NSUInteger)index;

/*!
 @method mutableArrayAtIndex:defaultValue:
 @abstract 获取指定index的NSMutableArray类型值
 @param index 索引号
 @param defaultValue 获取失败要返回的值
 @result 返回NSMutableArray,获取失败为指定的defaultValue
 */
- (NSMutableArray *)mutableArrayAtIndex:(NSUInteger)index defaultValue:(NSArray *)defaultValue;

/*!
 @method dictionaryAtIndex:
 @abstract 获取指定index的NSDictionary类型值
 @param index 索引号
 @result 返回NSDictionary,获取失败为nil
 */
- (NSDictionary *)dictionaryAtIndex:(NSUInteger)index;

/*!
 @method dictionaryAtIndex:defaultValue:
 @abstract 获取指定index的NSDictionary类型值
 @param index 索引号
 @param defaultValue 获取失败要返回的值
 @result 返回NSDictionary,获取失败为指定的defaultValue
 */
- (NSDictionary *)dictionaryAtIndex:(NSUInteger)index defaultValue:(NSDictionary *)defaultValue;

/*!
 @method mutableDictionaryAtIndex:
 @abstract 获取指定index的NSMutableDictionary类型值
 @param index 索引号
 @result 返回NSMutableDictionary,获取失败为nil
 */
- (NSMutableDictionary *)mutableDictionaryAtIndex:(NSUInteger)index;

/*!
 @method mutableDictionaryAtIndex:defaultValue:
 @abstract 获取指定index的NSMutableDictionary类型值
 @param index 索引号
 @param defaultValue 获取失败要返回的值
 @result 返回NSMutableDictionary,获取失败为指定的defaultValue
 */
- (NSMutableDictionary *)mutableDictionaryAtIndex:(NSUInteger)index defaultValue:(NSDictionary *)defaultValue;

/*!
 @method dataAtIndex:
 @abstract 获取指定index的NSData类型值
 @param index 索引号
 @result 返回NSData,获取失败为nil
 */
- (NSData *)dataAtIndex:(NSUInteger)index;

/*!
 @method dataAtIndex:defaultValue:
 @abstract 获取指定index的NSData类型值
 @param index 索引号
 @param defaultValue 获取失败要返回的值
 @result 返回NSData,获取失败为指定的defaultValue
 */
- (NSData *)dataAtIndex:(NSUInteger)index defaultValue:(NSData *)defaultValue;

/*!
 @method stringAtIndex:
 @abstract 获取指定index的NSString类型值
 @param index 索引号
 @result 返回NSString,获取失败为nil
 */
- (NSString *)stringAtIndex:(NSUInteger)index;

/*!
 @method stringAtIndexToString:
 @abstract 获取指定index的NSString类型值
 @param index 索引号
 @result 返回字NSString,获取失败为@""
 */
- (NSString *)stringAtIndexToString:(NSUInteger)index;

/*!
 @method stringAtIndex:defaultValue:
 @abstract 获取指定index的NSString类型值,获取失败返回为指定的defaultValue
 @param index 索引号
 @param defaultValue 获取失败要返回的值
 @result 返回NSString,获取失败为指定的defaultValue
 */
- (NSString *)stringAtIndex:(NSUInteger)index defaultValue:(NSString *)defaultValue;

/*!
 @method numberAtIndex:
 @abstract 获取指定index的NSNumber类型值
 @param index 索引号
 @result 返回NSNumber,获取失败为nil
 */
- (NSNumber *)numberAtIndex:(NSUInteger)index;

/*!
 @method numberAtIndex:defaultValue:
 @abstract 获取指定index的NSNumber类型值
 @param index 索引号
 @param defaultValue 获取失败要返回的值
 @result 返回NSNumber,获取失败为指定的defaultValue
 */
- (NSNumber *)numberAtIndex:(NSUInteger)index defaultValue:(NSNumber *)defaultValue;

/*!
 @method charAtIndex:
 @abstract 获取指定index的NSNumber类型值
 @param index 索引号
 @result 返回char
 */
- (char)charAtIndex:(NSUInteger)index;

/*!
 @method unsignedCharAtIndex:
 @abstract 获取指定index的unsigned char类型值
 @param index 索引号
 @result 返回unsigned char
 */
- (unsigned char)unsignedCharAtIndex:(NSUInteger)index;

/*!
 @method shortAtIndex:
 @abstract 获取指定index的short类型值
 @param index 索引号
 @result 返回short,获取失败为0
 */
- (short)shortAtIndex:(NSUInteger)index;

/*!
 @method shortAtIndex:defaultValue:
 @abstract 获取指定index的short类型值
 @param index 索引号
 @param defaultValue 获取失败要返回的值
 @result 返回short,获取失败为指定的defaultValue
 */
- (short)shortAtIndex:(NSUInteger)index defaultValue:(short)defaultValue;

/*!
 @method unsignedShortAtIndex:
 @abstract 获取指定index的unsigned short类型值
 @param index 索引号
 @result 返回unsigned short,获取失败为0
 */
- (unsigned short)unsignedShortAtIndex:(NSUInteger)index;

/*!
 @method unsignedShortAtIndex:defaultValue:
 @abstract 获取指定index的unsigned short类型值
 @param index 索引号
 @param defaultValue 获取失败要返回的值
 @result 返回unsigned short,获取失败为指定的defaultValue
 */
- (unsigned short)unsignedShortAtIndex:(NSUInteger)index defaultValue:(unsigned short)defaultValue;

/*!
 @method intAtIndex:
 @abstract 获取指定index的int类型值
 @param index 索引号
 @result 返回int,获取失败为0
 */
- (int)intAtIndex:(NSUInteger)index;

/*!
 @method intAtIndex:defaultValue:
 @abstract 获取指定index的int类型值
 @param index 索引号
 @param defaultValue 获取失败要返回的值
 @result 返回int,获取失败为指定的defaultValue
 */
- (int)intAtIndex:(NSUInteger)index defaultValue:(int)defaultValue;

/*!
 @method unsignedIntAtIndex:
 @abstract 获取指定index的unsigned int类型值
 @param index 索引号
 @result 返回unsigned int,获取失败为0
 */
- (unsigned int)unsignedIntAtIndex:(NSUInteger)index;

/*!
 @method unsignedIntAtIndex:defaultValue:
 @abstract 获取指定index的unsigned int类型值
 @param index 索引号
 @param defaultValue 获取失败要返回的值
 @result 返回unsigned int,获取失败为指定的defaultValue
 */
- (unsigned int)unsignedIntAtIndex:(NSUInteger)index defaultValue:(unsigned int)defaultValue;

/*!
 @method longAtIndex:
 @abstract 获取指定index的long类型值
 @param index 索引号
 @result 返回long,获取失败为0
 */
- (long)longAtIndex:(NSUInteger)index;

/*!
 @method longAtIndex:defaultValue:
 @abstract 获取指定index的long类型值
 @param defaultValue 获取失败要返回的值
 @result 返回long,获取失败为指定的defaultValue
 */
- (long)longAtIndex:(NSUInteger)index defaultValue:(long)defaultValue;

/*!
 @method unsignedLongAtIndex:
 @abstract 获取指定index的unsigned long类型值
 @param index 索引号
 @result 返回unsigned long,获取失败为0
 */
- (unsigned long)unsignedLongAtIndex:(NSUInteger)index;

/*!
 @method unsignedLongAtIndex:defaultValue:
 @abstract 获取指定index的unsigned long类型值
 @param index 索引号
 @param defaultValue 获取失败要返回的值
 @result 返回unsigned long,获取失败为指定的defaultValue
 */
- (unsigned long)unsignedLongAtIndex:(NSUInteger)index defaultValue:(unsigned long)defaultValue;

/*!
 @method longLongAtIndex:
 @abstract 获取指定index的long long类型值
 @param index 索引号
 @result 返回long long,获取失败为0
 */
- (long long)longLongAtIndex:(NSUInteger)index;

/*!
 @method longLongAtIndex:defaultValue:
 @abstract 获取指定index的long long类型值
 @param index 索引号
 @param defaultValue 获取失败要返回的值
 @result 返回long long,获取失败为指定的defaultValue
 */
- (long long)longLongAtIndex:(NSUInteger)index defaultValue:(long long)defaultValue;

/*!
 @method unsignedLongLongAtIndex:
 @abstract 获取指定index的unsigned long long类型值
 @param index 索引号
 @result 返回unsigned long long,获取失败为0
 */
- (unsigned long long)unsignedLongLongAtIndex:(NSUInteger)index;

/*!
 @method unsignedLongLongAtIndex:defaultValue:
 @abstract 获取指定index的unsigned long long类型值
 @param index 索引号
 @param defaultValue 获取失败要返回的值
 @result 返回unsigned long long,获取失败为指定的defaultValue
 */
- (unsigned long long)unsignedLongLongAtIndex:(NSUInteger)index defaultValue:(unsigned long long)defaultValue;

/*!
 @method floatAtIndex:
 @abstract 获取指定index的float类型值
 @param index 索引号
 @result 返回float,获取失败为0.0
 */
- (float)floatAtIndex:(NSUInteger)index;

/*!
 @method floatAtIndex:defaultValue:
 @abstract 获取指定index的float类型值
 @param index 索引号
 @param defaultValue 获取失败要返回的值
 @result 返回float,获取失败为指定的defaultValue
 */
- (float)floatAtIndex:(NSUInteger)index defaultValue:(float)defaultValue;

/*!
 @method doubleAtIndex:
 @abstract 获取指定index的double类型值
 @param index 索引号
 @result 返回double,获取失败为0.0
 */
- (double)doubleAtIndex:(NSUInteger)index;

/*!
 @method doubleAtIndex:defaultValue:
 @abstract 获取指定index的double类型值
 @param index 索引号
 @param defaultValue 获取失败要返回的值
 @result 返回double,获取失败为指定的defaultValue
 */
- (double)doubleAtIndex:(NSUInteger)index defaultValue:(double)defaultValue;

/*!
 @method boolAtIndex:
 @abstract 获取指定index的BOOL类型值
 @param index 索引号
 @result 返回BOOL,获取失败为NO
 */
- (BOOL)boolAtIndex:(NSUInteger)index;

/*!
 @method boolAtIndex:
 @abstract 获取指定index的BOOL类型值
 @param index 索引号
 @param defaultValue 获取失败要返回的值
 @result 返回BOOL,获取失败为指定的defaultValue
 */
- (BOOL)boolAtIndex:(NSUInteger)index defaultValue:(BOOL)defaultValue;

/*!
 @method integerAtIndex:
 @abstract 获取指定index的NSInteger类型值
 @param index 索引号
 @result 返回NSInteger,获取失败为0
 */
- (NSInteger)integerAtIndex:(NSUInteger)index;

/*!
 @method integerAtIndex:defaultValue:
 @abstract 获取指定index的NSInteger类型值
 @param index 索引号
 @param defaultValue 获取失败要返回的值
 @result 返回NSInteger,获取失败为指定的defaultValue
 */
- (NSInteger)integerAtIndex:(NSUInteger)index defaultValue:(NSInteger)defaultValue;

/*!
 @method unsignedIntegerAtIndex:
 @abstract 获取指定index的NSUInteger类型值
 @param index 索引号
 @result 返回NSUInteger,获取失败为0
 */
- (NSUInteger)unsignedIntegerAtIndex:(NSUInteger)index;

/*!
 @method unsignedIntegerAtIndex:defaultValue:
 @abstract 获取指定index的NSUInteger类型值
 @param index 索引号
 @param defaultValue 获取失败要返回的值
 @result 返回NSUInteger,获取失败为指定的defaultValue
 */
- (NSUInteger)unsignedIntegerAtIndex:(NSUInteger)index defaultValue:(NSUInteger)defaultValue;

/*!
 @method pointAtIndex:
 @abstract 获取指定index的CGPoint类型值
 @param index 索引号
 @result 返回CGPoint,获取失败为CGPointZero
 */
- (CGPoint)pointAtIndex:(NSUInteger)index;

/*!
 @method pointAtIndex:defaultValue:
 @abstract 获取指定index的CGPoint类型值
 @param index 索引号
 @param defaultValue 获取失败要返回的值
 @result 返回CGPoint,获取失败为指定的defaultValue
 */
- (CGPoint)pointAtIndex:(NSUInteger)index defaultValue:(CGPoint)defaultValue;

/*!
 @method sizeAtIndex:
 @abstract 获取指定index的CGSize类型值
 @param index 索引号
 @result 返回CGPoint,获取失败为CGSizeZero
 */
- (CGSize)sizeAtIndex:(NSUInteger)index;

/*!
 @method sizeAtIndex:defaultValue:
 @abstract 获取指定index的CGSize类型值
 @param index 索引号
 @param defaultValue 获取失败要返回的值
 @result 返回CGSize,获取失败为指定的defaultValue
 */
- (CGSize)sizeAtIndex:(NSUInteger)index defaultValue:(CGSize)defaultValue;

/*!
 @method rectAtIndex:
 @abstract 获取指定index的CGRect类型值
 @param index 索引号
 @result 返回CGPoint,获取失败为CGRectZero
 */
- (CGRect)rectAtIndex:(NSUInteger)index;

/*!
 @method rectAtIndex:
 @abstract 获取指定index的CGRect类型值
 @param index 索引号
 @param defaultValue 获取失败要返回的值
 @result 返回CGRect,获取失败为指定的defaultValue
 */
- (CGRect)rectAtIndex:(NSUInteger)index defaultValue:(CGRect)defaultValue;

@end

@implementation NSArray (SHYUtil)

- (id)anyObject
{
    return [self count] > 0 ? [self objectAtIndexCheck:0] : nil;
}

- (BOOL)isEmpty
{
    return ([self count] == 0);
}

- (id)objectAtIndexCheck:(NSUInteger)index
{
    if (index >= [self count]) {
        return nil;
    }

    id value = [self objectAtIndex:index];
    if (value == [NSNull null]) {
        return nil;
    }
    return value;
}

- (id)objectAtIndexCheck:(NSUInteger)index class:(__unsafe_unretained Class)aClass
{
    return [self objectAtIndexCheck:index class:aClass defaultValue:nil];
}

- (id)objectAtIndexCheck:(NSUInteger)index class:(__unsafe_unretained Class)aClass defaultValue:(id)defaultValue
{
    id value = [self objectAtIndexCheck:index];
    if (![value isKindOfClass:aClass]) {
        return defaultValue;
    }
    return value;
}

- (NSArray *)arrayAtIndex:(NSUInteger)index
{
    return [self arrayAtIndex:index defaultValue:nil];
}

- (NSArray *)arrayAtIndex:(NSUInteger)index defaultValue:(NSArray *)defaultValue
{
    return [self objectAtIndexCheck:index class:[NSArray class] defaultValue:defaultValue];
}

- (NSMutableArray *)mutableArrayAtIndex:(NSUInteger)index
{
    return [self mutableArrayAtIndex:index defaultValue:nil];
}

- (NSMutableArray *)mutableArrayAtIndex:(NSUInteger)index defaultValue:(NSArray *)defaultValue
{
    return [self objectAtIndexCheck:index class:[NSMutableArray class] defaultValue:defaultValue];
}

- (NSDictionary *)dictionaryAtIndex:(NSUInteger)index
{
    return [self dictionaryAtIndex:index defaultValue:nil];
}

- (NSDictionary *)dictionaryAtIndex:(NSUInteger)index defaultValue:(NSDictionary *)defaultValue
{
    return [self objectAtIndexCheck:index class:[NSDictionary class] defaultValue:defaultValue];
}

- (NSMutableDictionary *)mutableDictionaryAtIndex:(NSUInteger)index
{
    return [self mutableDictionaryAtIndex:index defaultValue:nil];
}

- (NSMutableDictionary *)mutableDictionaryAtIndex:(NSUInteger)index defaultValue:(NSDictionary *)defaultValue
{
    return [self objectAtIndexCheck:index class:[NSMutableDictionary class] defaultValue:defaultValue];
}

- (NSData *)dataAtIndex:(NSUInteger)index
{
    return [self dataAtIndex:index defaultValue:nil];
}

- (NSData *)dataAtIndex:(NSUInteger)index defaultValue:(NSData *)defaultValue
{
    return [self objectAtIndexCheck:index class:[NSData class] defaultValue:defaultValue];
}

- (NSString *)stringAtIndex:(NSUInteger)index
{
    return [self stringAtIndex:index defaultValue:nil];
}

- (NSString *)stringAtIndexToString:(NSUInteger)index
{
    return [self stringAtIndex:index defaultValue:@""];
}

- (NSString *)stringAtIndex:(NSUInteger)index defaultValue:(NSString *)defaultValue
{
    id value = [self objectAtIndexCheck:index];

    if ([value isKindOfClass:[NSNumber class]]) {
        return [value stringValue];
    }

    if (![value isKindOfClass:[NSString class]]) {
        return defaultValue;
    }
    return value;
}

- (NSNumber *)numberAtIndex:(NSUInteger)index
{
    return [self numberAtIndex:index defaultValue:nil];
}

- (NSNumber *)numberAtIndex:(NSUInteger)index defaultValue:(NSNumber *)defaultValue
{
    id value = [self objectAtIndexCheck:index];
    if ([value isKindOfClass:[NSString class]]) {
        return [value numberValue];
    }

    if (![value isKindOfClass:[NSNumber class]]) {
        return defaultValue;
    }

    return value;
}

- (char)charAtIndex:(NSUInteger)index
{
    id value = [self objectAtIndexCheck:index];
    if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
        return [value charValue];
    }
    else {
        return 0x0;
    }
}

- (unsigned char)unsignedCharAtIndex:(NSUInteger)index
{
    id value = [self objectAtIndexCheck:index];
    if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
        return [value unsignedCharValue];
    }
    else {
        return 0x0;
    }
}

- (short)shortAtIndex:(NSUInteger)index
{
    return [self shortAtIndex:index defaultValue:0];
}

- (short)shortAtIndex:(NSUInteger)index defaultValue:(short)defaultValue
{
    id value = [self objectAtIndexCheck:index];
    if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
        return [value shortValue];
    }
    else {
        return defaultValue;
    }
}

- (unsigned short)unsignedShortAtIndex:(NSUInteger)index
{
    return [self unsignedShortAtIndex:index defaultValue:0];
}

- (unsigned short)unsignedShortAtIndex:(NSUInteger)index defaultValue:(unsigned short)defaultValue
{
    id value = [self objectAtIndexCheck:index];
    if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
        return [value unsignedShortValue];
    }
    else {
        return defaultValue;
    }
}

- (int)intAtIndex:(NSUInteger)index
{
    return [self intAtIndex:index defaultValue:0];
}

- (int)intAtIndex:(NSUInteger)index defaultValue:(int)defaultValue
{
    id value = [self objectAtIndexCheck:index];
    if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
        return [value intValue];
    }
    else {
        return defaultValue;
    }
}

- (unsigned int)unsignedIntAtIndex:(NSUInteger)index
{
    return [self unsignedIntAtIndex:index defaultValue:0];
}

- (unsigned int)unsignedIntAtIndex:(NSUInteger)index defaultValue:(unsigned int)defaultValue
{
    id value = [self objectAtIndexCheck:index];
    if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
        return [value unsignedIntValue];
    }
    else {
        return defaultValue;
    }
}

- (long)longAtIndex:(NSUInteger)index
{
    return [self longAtIndex:index defaultValue:0];
}

- (long)longAtIndex:(NSUInteger)index defaultValue:(long)defaultValue
{
    id value = [self objectAtIndexCheck:index];
    if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
        return [value longValue];
    }
    else {
        return defaultValue;
    }
}

- (unsigned long)unsignedLongAtIndex:(NSUInteger)index
{
    return [self unsignedLongAtIndex:index defaultValue:0];
}

- (unsigned long)unsignedLongAtIndex:(NSUInteger)index defaultValue:(unsigned long)defaultValue
{
    id value = [self objectAtIndexCheck:index];
    if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
        return [value unsignedLongValue];
    }
    else {
        return defaultValue;
    }
}

- (long long)longLongAtIndex:(NSUInteger)index
{
    return [self longLongAtIndex:index defaultValue:0];
}

- (long long)longLongAtIndex:(NSUInteger)index defaultValue:(long long)defaultValue
{
    id value = [self objectAtIndexCheck:index];
    if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
        return [value longLongValue];
    }
    else {
        return defaultValue;
    }
}

- (unsigned long long)unsignedLongLongAtIndex:(NSUInteger)index
{
    return [self unsignedLongLongAtIndex:index defaultValue:0];
}

- (unsigned long long)unsignedLongLongAtIndex:(NSUInteger)index defaultValue:(unsigned long long)defaultValue
{
    id value = [self objectAtIndexCheck:index];
    if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
        return [value unsignedLongLongValue];
    }
    else {
        return defaultValue;
    }
}

- (float)floatAtIndex:(NSUInteger)index
{
    return [self floatAtIndex:index defaultValue:0.0];
}

- (float)floatAtIndex:(NSUInteger)index defaultValue:(float)defaultValue
{
    id value = [self objectAtIndexCheck:index];
    if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
        float result = [value floatValue];
        return isnan(result) ? defaultValue : result;
    }
    else {
        return defaultValue;
    }
}

- (double)doubleAtIndex:(NSUInteger)index
{
    return [self doubleAtIndex:index defaultValue:0.0];
}

- (double)doubleAtIndex:(NSUInteger)index defaultValue:(double)defaultValue
{
    id value = [self objectAtIndexCheck:index];
    if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
        double result = [value doubleValue];
        return isnan(result) ? defaultValue : result;
    }
    else {
        return defaultValue;
    }
}

- (BOOL)boolAtIndex:(NSUInteger)index
{
    return [self boolAtIndex:index defaultValue:NO];
}

- (BOOL)boolAtIndex:(NSUInteger)index defaultValue:(BOOL)defaultValue
{
    id value = [self objectAtIndexCheck:index];
    if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
        return [value boolValue];
    }
    else {
        return defaultValue;
    }
}

- (NSInteger)integerAtIndex:(NSUInteger)index
{
    return [self integerAtIndex:index defaultValue:0];
}

- (NSInteger)integerAtIndex:(NSUInteger)index defaultValue:(NSInteger)defaultValue
{
    id value = [self objectAtIndexCheck:index];
    if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
        return [value integerValue];
    }
    else {
        return defaultValue;
    }
}

- (NSUInteger)unsignedIntegerAtIndex:(NSUInteger)index
{
    return [self unsignedIntegerAtIndex:index defaultValue:0];
}

- (NSUInteger)unsignedIntegerAtIndex:(NSUInteger)index defaultValue:(NSUInteger)defaultValue
{
    id value = [self objectAtIndexCheck:index];
    if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
        return [value unsignedIntegerValue];
    }
    else {
        return defaultValue;
    }
}

- (CGPoint)pointAtIndex:(NSUInteger)index
{
    return [self pointAtIndex:index defaultValue:CGPointZero];
}

- (CGPoint)pointAtIndex:(NSUInteger)index defaultValue:(CGPoint)defaultValue
{
    id value = [self objectAtIndexCheck:index];
    if ([value isKindOfClass:[NSString class]] && ![value isEmpty])
        return CGPointFromString(value);
    else if ([value isKindOfClass:[NSValue class]])
        return [value CGPointValue];
    else
        return defaultValue;
}

- (CGSize)sizeAtIndex:(NSUInteger)index
{
    return [self sizeAtIndex:index defaultValue:CGSizeZero];
}

- (CGSize)sizeAtIndex:(NSUInteger)index defaultValue:(CGSize)defaultValue
{
    id value = [self objectAtIndexCheck:index];
    if ([value isKindOfClass:[NSString class]] && ![value isEmpty])
        return CGSizeFromString(value);
    else if ([value isKindOfClass:[NSValue class]])
        return [value CGSizeValue];
    else
        return defaultValue;
}

- (CGRect)rectAtIndex:(NSUInteger)index
{
    return [self rectAtIndex:index defaultValue:CGRectZero];
}

- (CGRect)rectAtIndex:(NSUInteger)index defaultValue:(CGRect)defaultValue
{
    id value = [self objectAtIndexCheck:index];
    if ([value isKindOfClass:[NSString class]] && ![value isEmpty])
        return CGRectFromString(value);
    else if ([value isKindOfClass:[NSValue class]])
        return [value CGRectValue];
    else
        return defaultValue;
}

@end
NSDictionary的扩展
@interface NSDictionary (SHYUtil)

/*!
 @method dictionaryWithContentsOfData:
 @abstract 把NSData数据转成NSDictionary
 @result 返回NSDictionary
 */
+ (NSDictionary *)dictionaryWithContentsOfData:(NSData *)data;

/*!
 @method isEmpty
 @abstract 是否空,字典里没有对象也是为YES;
 @result 返回bool
 */
- (BOOL)isEmpty;

/*!
 @method objectForKeyCheck
 @abstract 检查是否aKey为nil 和 NSNull null如果是返回nil
 @result 返回对象
 */
- (id)objectForKeyCheck:(id)aKey;

/*!
 @method objectForKeyCheck:class:
 @abstract 获取指定key的对象
 @param key 键
 @param aClass 检查类型
 @result 返回对象
 */
- (id)objectForKeyCheck:(id)key class:(__unsafe_unretained Class)aClass;

/*!
 @method objectForKeyCheck:class:defaultValue:
 @abstract 获取指定key的对象
 @param key 键
 @param aClass 检查类型
 @param defaultValue 获取失败要返回的值
 @result 返回对象,获取失败为指定的defaultValue
 */
- (id)objectForKeyCheck:(id)key class:(__unsafe_unretained Class)aClass defaultValue:(id)defaultValue;

/*!
 @method arrayForKey:
 @abstract 获取指定key的NSArray类型值
 @param key 键
 @result 返回NSArray,获取失败为nil
 */
- (NSArray *)arrayForKey:(id)key;

/*!
 @method arrayForKey:defaultValue:
 @abstract 获取指定key的NSArray类型值
 @param key 键
 @param defaultValue 获取失败要返回的值
 @result 返回NSArray,获取失败为指定的defaultValue
 */
- (NSArray *)arrayForKey:(id)key defaultValue:(NSArray *)defaultValue;

/*!
 @method mutableArrayForKey:
 @abstract 获取指定key的NSMutableArray类型值
 @param key 键
 @result 返回NSMutableArray,获取失败为nil
 */
- (NSMutableArray *)mutableArrayForKey:(id)key;

/*!
 @method mutableArrayForKey:defaultValue:
 @abstract 获取指定key的NSMutableArray类型值
 @param key 键
 @param defaultValue 获取失败要返回的值
 @result 返回NSMutableArray,获取失败为指定的defaultValue
 */
- (NSMutableArray *)mutableArrayForKey:(id)key defaultValue:(NSArray *)defaultValue;

/*!
 @method dictionaryForKey:
 @abstract 获取指定key的NSDictionary类型值
 @param key 键
 @result 返回NSDictionary,获取失败为nil
 */
- (NSDictionary *)dictionaryForKey:(id)key;

/*!
 @method dictionaryForKey:defaultValue:
 @abstract 获取指定key的NSDictionary类型值
 @param key 键
 @param defaultValue 获取失败要返回的值
 @result 返回NSDictionary,获取失败为指定的defaultValue
 */
- (NSDictionary *)dictionaryForKey:(id)key defaultValue:(NSDictionary *)defaultValue;

/*!
 @method mutableDictionaryForKey:
 @abstract 获取指定key的NSMutableDictionary类型值
 @param key 键
 @result 返回NSMutableDictionary,获取失败为nil
 */
- (NSMutableDictionary *)mutableDictionaryForKey:(id)key;

/*!
 @method mutableDictionaryForKey:defaultValue:
 @abstract 获取指定key的NSMutableDictionary类型值
 @param key 键
 @param defaultValue 获取失败要返回的值
 @result 返回NSMutableDictionary,获取失败为指定的defaultValue
 */
- (NSMutableDictionary *)mutableDictionaryForKey:(id)key defaultValue:(NSDictionary *)defaultValue;

/*!
 @method dataForKey:
 @abstract 获取指定key的NSData类型值
 @param key 键
 @result 返回NSData,获取失败为nil
 */
- (NSData *)dataForKey:(id)key;

/*!
 @method dataForKey:defaultValue:
 @abstract 获取指定key的NSData类型值
 @param key 键
 @param defaultValue 获取失败要返回的值
 @result 返回NSData,获取失败为指定的defaultValue
 */
- (NSData *)dataForKey:(id)key defaultValue:(NSData *)defaultValue;

/*!
 @method stringForKey:
 @abstract 获取指定key的NSString类型值
 @param key 键
 @result 返回NSString,获取失败为nil
 */
- (NSString *)stringForKey:(id)key;

/*!
 @method stringForKeyToString:
 @abstract 获取指定key的NSString类型值
 @param key 键
 @result 返回字NSString,获取失败为@""
 */
- (NSString *)stringForKeyToString:(id)key;

/*!
 @method stringForKey:defaultValue:
 @abstract 获取指定key的NSString类型值,获取失败返回为指定的defaultValue
 @param key 键
 @param defaultValue 获取失败要返回的值
 @result 返回NSString,获取失败为指定的defaultValue
 */
- (NSString *)stringForKey:(id)key defaultValue:(NSString *)defaultValue;

/*!
 @method numberForKey:
 @abstract 获取指定key的NSNumber类型值
 @param key 键
 @result 返回NSNumber,获取失败为nil
 */
- (NSNumber *)numberForKey:(id)key;

/*!
 @method numberForKey:defaultValue:
 @abstract 获取指定key的NSNumber类型值
 @param key 键
 @param defaultValue 获取失败要返回的值
 @result 返回NSNumber,获取失败为指定的defaultValue
 */
- (NSNumber *)numberForKey:(id)key defaultValue:(NSNumber *)defaultValue;

/*!
 @method charForKey:
 @abstract 获取指定key的NSNumber类型值
 @param key 键
 @result 返回char
 */
- (char)charForKey:(id)key;

/*!
 @method unsignedCharForKey:
 @abstract 获取指定key的unsigned char类型值
 @param key 键
 @result 返回unsigned char
 */
- (unsigned char)unsignedCharForKey:(id)key;

/*!
 @method shortForKey:
 @abstract 获取指定key的short类型值
 @param key 键
 @result 返回short,获取失败为0
 */
- (short)shortForKey:(id)key;

/*!
 @method shortForKey:defaultValue:
 @abstract 获取指定key的short类型值
 @param key 键
 @param defaultValue 获取失败要返回的值
 @result 返回short,获取失败为指定的defaultValue
 */
- (short)shortForKey:(id)key defaultValue:(short)defaultValue;

/*!
 @method unsignedShortForKey:
 @abstract 获取指定key的unsigned short类型值
 @param key 键
 @result 返回unsigned short,获取失败为0
 */
- (unsigned short)unsignedShortForKey:(id)key;

/*!
 @method unsignedShortForKey:defaultValue:
 @abstract 获取指定key的unsigned short类型值
 @param key 键
 @param defaultValue 获取失败要返回的值
 @result 返回unsigned short,获取失败为指定的defaultValue
 */
- (unsigned short)unsignedShortForKey:(id)key defaultValue:(unsigned short)defaultValue;

/*!
 @method intForKey:
 @abstract 获取指定key的int类型值
 @param key 键
 @result 返回int,获取失败为0
 */
- (int)intForKey:(id)key;

/*!
 @method intForKey:defaultValue:
 @abstract 获取指定key的int类型值
 @param key 键
 @param defaultValue 获取失败要返回的值
 @result 返回int,获取失败为指定的defaultValue
 */
- (int)intForKey:(id)key defaultValue:(int)defaultValue;

/*!
 @method unsignedIntForKey:
 @abstract 获取指定key的unsigned int类型值
 @param key 键
 @result 返回unsigned int,获取失败为0
 */
- (unsigned int)unsignedIntForKey:(id)key;

/*!
 @method unsignedIntForKey:defaultValue:
 @abstract 获取指定key的unsigned int类型值
 @param key 键
 @param defaultValue 获取失败要返回的值
 @result 返回unsigned int,获取失败为指定的defaultValue
 */
- (unsigned int)unsignedIntForKey:(id)key defaultValue:(unsigned int)defaultValue;

/*!
 @method longForKey:
 @abstract 获取指定key的long类型值
 @param key 键
 @result 返回long,获取失败为0
 */
- (long)longForKey:(id)key;

/*!
 @method longForKey:defaultValue:
 @abstract 获取指定key的long类型值
 @param defaultValue 获取失败要返回的值
 @result 返回long,获取失败为指定的defaultValue
 */
- (long)longForKey:(id)key defaultValue:(long)defaultValue;

/*!
 @method unsignedLongForKey:
 @abstract 获取指定key的unsigned long类型值
 @param key 键
 @result 返回unsigned long,获取失败为0
 */
- (unsigned long)unsignedLongForKey:(id)key;

/*!
 @method unsignedLongForKey:defaultValue:
 @abstract 获取指定key的unsigned long类型值
 @param key 键
 @param defaultValue 获取失败要返回的值
 @result 返回unsigned long,获取失败为指定的defaultValue
 */
- (unsigned long)unsignedLongForKey:(id)key defaultValue:(unsigned long)defaultValue;

/*!
 @method longLongForKey:
 @abstract 获取指定key的long long类型值
 @param key 键
 @result 返回long long,获取失败为0
 */
- (long long)longLongForKey:(id)key;

/*!
 @method longLongForKey:defaultValue:
 @abstract 获取指定key的long long类型值
 @param key 键
 @param defaultValue 获取失败要返回的值
 @result 返回long long,获取失败为指定的defaultValue
 */
- (long long)longLongForKey:(id)key defaultValue:(long long)defaultValue;

/*!
 @method unsignedLongLongForKey:
 @abstract 获取指定key的unsigned long long类型值
 @param key 键
 @result 返回unsigned long long,获取失败为0
 */
- (unsigned long long)unsignedLongLongForKey:(id)key;

/*!
 @method unsignedLongLongForKey:defaultValue:
 @abstract 获取指定key的unsigned long long类型值
 @param key 键
 @param defaultValue 获取失败要返回的值
 @result 返回unsigned long long,获取失败为指定的defaultValue
 */
- (unsigned long long)unsignedLongLongForKey:(id)key defaultValue:(unsigned long long)defaultValue;

/*!
 @method floatForKey:
 @abstract 获取指定key的float类型值
 @param key 键
 @result 返回float,获取失败为0.0
 */
- (float)floatForKey:(id)key;

/*!
 @method floatForKey:defaultValue:
 @abstract 获取指定key的float类型值
 @param key 键
 @param defaultValue 获取失败要返回的值
 @result 返回float,获取失败为指定的defaultValue
 */
- (float)floatForKey:(id)key defaultValue:(float)defaultValue;

/*!
 @method doubleForKey:
 @abstract 获取指定key的double类型值
 @param key 键
 @result 返回double,获取失败为0.0
 */
- (double)doubleForKey:(id)key;

/*!
 @method doubleForKey:defaultValue:
 @abstract 获取指定key的double类型值
 @param key 键
 @param defaultValue 获取失败要返回的值
 @result 返回double,获取失败为指定的defaultValue
 */
- (double)doubleForKey:(id)key defaultValue:(double)defaultValue;

/*!
 @method boolForKey:
 @abstract 获取指定key的BOOL类型值
 @param key 键
 @result 返回BOOL,获取失败为NO
 */
- (BOOL)boolForKey:(id)key;

/*!
 @method boolForKey:
 @abstract 获取指定key的BOOL类型值
 @param key 键
 @param defaultValue 获取失败要返回的值
 @result 返回BOOL,获取失败为指定的defaultValue
 */
- (BOOL)boolForKey:(id)key defaultValue:(BOOL)defaultValue;

/*!
 @method integerForKey:
 @abstract 获取指定key的NSInteger类型值
 @param key 键
 @result 返回NSInteger,获取失败为0
 */
- (NSInteger)integerForKey:(id)key;

/*!
 @method integerForKey:defaultValue:
 @abstract 获取指定key的NSInteger类型值
 @param key 键
 @param defaultValue 获取失败要返回的值
 @result 返回NSInteger,获取失败为指定的defaultValue
 */
- (NSInteger)integerForKey:(id)key defaultValue:(NSInteger)defaultValue;

/*!
 @method unsignedIntegerForKey:
 @abstract 获取指定key的NSUInteger类型值
 @param key 键
 @result 返回NSUInteger,获取失败为0
 */
- (NSUInteger)unsignedIntegerForKey:(id)key;

/*!
 @method unsignedIntegerForKey:defaultValue:
 @abstract 获取指定key的NSUInteger类型值
 @param key 键
 @param defaultValue 获取失败要返回的值
 @result 返回NSUInteger,获取失败为指定的defaultValue
 */
- (NSUInteger)unsignedIntegerForKey:(id)key defaultValue:(NSUInteger)defaultValue;

/*!
 @method pointForKey:
 @abstract 获取指定key的CGPoint类型值
 @param key 键
 @result 返回CGPoint,获取失败为CGPointZero
 */
- (CGPoint)pointForKey:(id)key;

/*!
 @method pointForKey:defaultValue:
 @abstract 获取指定key的CGPoint类型值
 @param key 键
 @param defaultValue 获取失败要返回的值
 @result 返回CGPoint,获取失败为指定的defaultValue
 */
- (CGPoint)pointForKey:(id)key defaultValue:(CGPoint)defaultValue;

/*!
 @method sizeForKey:
 @abstract 获取指定key的CGSize类型值
 @param key 键
 @result 返回CGPoint,获取失败为CGSizeZero
 */
- (CGSize)sizeForKey:(id)key;

/*!
 @method sizeForKey:defaultValue:
 @abstract 获取指定key的CGSize类型值
 @param key 键
 @param defaultValue 获取失败要返回的值
 @result 返回CGSize,获取失败为指定的defaultValue
 */
- (CGSize)sizeForKey:(id)key defaultValue:(CGSize)defaultValue;

/*!
 @method rectForKey:
 @abstract 获取指定key的CGRect类型值
 @param key 键
 @result 返回CGPoint,获取失败为CGRectZero
 */
- (CGRect)rectForKey:(id)key;

/*!
 @method rectForKey:
 @abstract 获取指定key的CGRect类型值
 @param key 键
 @param defaultValue 获取失败要返回的值
 @result 返回CGRect,获取失败为指定的defaultValue
 */
- (CGRect)rectForKey:(id)key defaultValue:(CGRect)defaultValue;

@end

@implementation NSDictionary (SHYUtil)

+ (NSDictionary *)dictionaryWithContentsOfData:(NSData *)data
{
    CFPropertyListRef plist =  CFPropertyListCreateFromXMLData(kCFAllocatorDefault, (__bridge CFDataRef)data, kCFPropertyListImmutable, NULL);
    NSDictionary *result = (__bridge_transfer NSDictionary *)plist;
    if ([result isKindOfClass:[NSDictionary class]]) {
        return result;
    }
    else {
        CFRelease(plist);
        return nil;
    }
}

- (BOOL)isEmpty
{
    return ([self count] == 0);
}

- (id)objectForKeyCheck:(id)aKey
{
    if (aKey == nil) {
        return nil;
    }

    id value = [self objectForKey:aKey];
    if (value == [NSNull null]) {
        return nil;
    }
    return value;
}

- (id)objectForKeyCheck:(id)key class:(__unsafe_unretained Class)aClass
{
    return [self objectForKeyCheck:key class:aClass defaultValue:nil];
}

- (id)objectForKeyCheck:(id)key class:(__unsafe_unretained Class)aClass defaultValue:(id)defaultValue
{
    id value = [self objectForKeyCheck:key];
    if (![value isKindOfClass:aClass]) {
        return defaultValue;
    }
    return value;
}

- (NSArray *)arrayForKey:(id)key
{
    return [self arrayForKey:key defaultValue:nil];
}

- (NSArray *)arrayForKey:(id)key defaultValue:(NSArray *)defaultValue
{
    return [self objectForKeyCheck:key class:[NSArray class] defaultValue:defaultValue];
}

- (NSMutableArray *)mutableArrayForKey:(id)key
{
    return [self mutableArrayForKey:key defaultValue:nil];
}

- (NSMutableArray *)mutableArrayForKey:(id)key defaultValue:(NSArray *)defaultValue
{
    return [self objectForKeyCheck:key class:[NSMutableArray class] defaultValue:defaultValue];
}

- (NSDictionary *)dictionaryForKey:(id)key
{
    return [self dictionaryForKey:key defaultValue:nil];
}

- (NSDictionary *)dictionaryForKey:(id)key defaultValue:(NSDictionary *)defaultValue
{
    return [self objectForKeyCheck:key class:[NSDictionary class] defaultValue:defaultValue];
}

- (NSMutableDictionary *)mutableDictionaryForKey:(id)key
{
    return [self mutableDictionaryForKey:key defaultValue:nil];
}

- (NSMutableDictionary *)mutableDictionaryForKey:(id)key defaultValue:(NSDictionary *)defaultValue
{
    return [self objectForKeyCheck:key class:[NSMutableDictionary class] defaultValue:defaultValue];
}

- (NSData *)dataForKey:(id)key
{
    return [self dataForKey:key defaultValue:nil];
}

- (NSData *)dataForKey:(id)key defaultValue:(NSData *)defaultValue
{
    return [self objectForKeyCheck:key class:[NSData class] defaultValue:defaultValue];
}

- (NSString *)stringForKey:(id)key
{
    return [self stringForKey:key defaultValue:nil];
}

- (NSString *)stringForKeyToString:(id)key
{
    return [self stringForKey:key defaultValue:@""];
}

- (NSString *)stringForKey:(id)key defaultValue:(NSString *)defaultValue
{
    id value = [self objectForKeyCheck:key];

    if ([value isKindOfClass:[NSNumber class]]) {
        return [value stringValue];
    }

    if (![value isKindOfClass:[NSString class]]) {
        return defaultValue;
    }
    return value;
}

- (NSNumber *)numberForKey:(id)key
{
    return [self numberForKey:key defaultValue:nil];
}

- (NSNumber *)numberForKey:(id)key defaultValue:(NSNumber *)defaultValue
{
    id value = [self objectForKeyCheck:key];

    if ([value isKindOfClass:[NSString class]]) {
        return [value numberValue];
    }

    if (![value isKindOfClass:[NSNumber class]]) {
        return defaultValue;
    }

    return value;
}

- (char)charForKey:(id)key
{
    id value = [self objectForKeyCheck:key];
    if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
        return [value charValue];
    }
    else {
        return 0x0;
    }
}

- (unsigned char)unsignedCharForKey:(id)key
{
    id value = [self objectForKeyCheck:key];
    if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
        return [value unsignedCharValue];
    }
    else {
        return 0x0;
    }
}

- (short)shortForKey:(id)key
{
    return [self shortForKey:key defaultValue:0];
}

- (short)shortForKey:(id)key defaultValue:(short)defaultValue
{
    id value = [self objectForKeyCheck:key];
    if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
        return [value shortValue];
    }
    else {
        return defaultValue;
    }
}

- (unsigned short)unsignedShortForKey:(id)key
{
    return [self unsignedShortForKey:key defaultValue:0];
}

- (unsigned short)unsignedShortForKey:(id)key defaultValue:(unsigned short)defaultValue
{
    id value = [self objectForKeyCheck:key];
    if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
        return [value unsignedShortValue];
    }
    else {
        return defaultValue;
    }
}

- (int)intForKey:(id)key
{
    return [self intForKey:key defaultValue:0];
}

- (int)intForKey:(id)key defaultValue:(int)defaultValue
{
    id value = [self objectForKeyCheck:key];
    if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
        return [value intValue];
    }
    else {
        return defaultValue;
    }
}

- (unsigned int)unsignedIntForKey:(id)key
{
    return [self unsignedIntForKey:key defaultValue:0];
}

- (unsigned int)unsignedIntForKey:(id)key defaultValue:(unsigned int)defaultValue
{
    id value = [self objectForKeyCheck:key];
    if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
        return [value unsignedIntValue];
    }
    else {
        return defaultValue;
    }
}

- (long)longForKey:(id)key
{
    return [self longForKey:key defaultValue:0];
}

- (long)longForKey:(id)key defaultValue:(long)defaultValue
{
    id value = [self objectForKeyCheck:key];
    if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
        return [value longValue];
    }
    else {
        return defaultValue;
    }
}

- (unsigned long)unsignedLongForKey:(id)key
{
    return [self unsignedLongForKey:key defaultValue:0];
}

- (unsigned long)unsignedLongForKey:(id)key defaultValue:(unsigned long)defaultValue
{
    id value = [self objectForKeyCheck:key];
    if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
        return [value unsignedLongValue];
    }
    else {
        return defaultValue;
    }
}

- (long long)longLongForKey:(id)key
{
    return [self longLongForKey:key defaultValue:0];
}

- (long long)longLongForKey:(id)key defaultValue:(long long)defaultValue
{
    id value = [self objectForKeyCheck:key];
    if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
        return [value longLongValue];
    }
    else {
        return defaultValue;
    }
}

- (unsigned long long)unsignedLongLongForKey:(id)key
{
    return [self unsignedLongLongForKey:key defaultValue:0];
}

- (unsigned long long)unsignedLongLongForKey:(id)key defaultValue:(unsigned long long)defaultValue
{
    id value = [self objectForKeyCheck:key];
    if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
        return [value unsignedLongLongValue];
    }
    else {
        return defaultValue;
    }
}

- (float)floatForKey:(id)key
{
    return [self floatForKey:key defaultValue:0.0];
}

- (float)floatForKey:(id)key defaultValue:(float)defaultValue
{
    id value = [self objectForKeyCheck:key];
    if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
        float result = [value floatValue];
        return isnan(result) ? defaultValue : result;
    }
    else {
        return defaultValue;
    }
}

- (double)doubleForKey:(id)key
{
    return [self doubleForKey:key defaultValue:0.0];
}

- (double)doubleForKey:(id)key defaultValue:(double)defaultValue
{
    id value = [self objectForKeyCheck:key];
    if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
        double result = [value doubleValue];
        return isnan(result) ? defaultValue : result;
    }
    else {
        return defaultValue;
    }
}

- (BOOL)boolForKey:(id)key
{
    return [self boolForKey:key defaultValue:NO];
}

- (BOOL)boolForKey:(id)key defaultValue:(BOOL)defaultValue
{
    id value = [self objectForKeyCheck:key];
    if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
        return [value boolValue];
    }
    else {
        return defaultValue;
    }
}

- (NSInteger)integerForKey:(id)key
{
    return [self integerForKey:key defaultValue:0];
}

- (NSInteger)integerForKey:(id)key defaultValue:(NSInteger)defaultValue
{
    id value = [self objectForKeyCheck:key];
    if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
        return [value integerValue];
    }
    else {
        return defaultValue;
    }
}

- (NSUInteger)unsignedIntegerForKey:(id)key
{
    return [self unsignedIntegerForKey:key defaultValue:0];
}

- (NSUInteger)unsignedIntegerForKey:(id)key defaultValue:(NSUInteger)defaultValue
{
    id value = [self objectForKeyCheck:key];
    if ([value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]]) {
        return [value unsignedIntegerValue];
    }
    else {
        return defaultValue;
    }
}

- (CGPoint)pointForKey:(id)key
{
    return [self pointForKey:key defaultValue:CGPointZero];
}

- (CGPoint)pointForKey:(id)key defaultValue:(CGPoint)defaultValue
{
    id value = [self objectForKeyCheck:key];
    if ([value isKindOfClass:[NSString class]] && ![value isEmpty])
        return CGPointFromString(value);
    else if ([value isKindOfClass:[NSValue class]])
        return [value CGPointValue];
    else
        return defaultValue;
}

- (CGSize)sizeForKey:(id)key
{
    return [self sizeForKey:key defaultValue:CGSizeZero];
}

- (CGSize)sizeForKey:(id)key defaultValue:(CGSize)defaultValue
{
    id value = [self objectForKeyCheck:key];
    if ([value isKindOfClass:[NSString class]] && ![value isEmpty])
        return CGSizeFromString(value);
    else if ([value isKindOfClass:[NSValue class]])
        return [value CGSizeValue];
    else
        return defaultValue;
}

- (CGRect)rectForKey:(id)key
{
    return [self rectForKey:key defaultValue:CGRectZero];
}

- (CGRect)rectForKey:(id)key defaultValue:(CGRect)defaultValue
{
    id value = [self objectForKeyCheck:key];
    if ([value isKindOfClass:[NSString class]] && ![value isEmpty])
        return CGRectFromString(value);
    else if ([value isKindOfClass:[NSValue class]])
        return [value CGRectValue];
    else
        return defaultValue;
}

@end

以上扩展就可以实现设想目标了

解析如下JSON我们也可以省好多判断的代码了如图:

这样方便了好多;容错目的也达到了;Crash也不因服务器改动而增加

时间: 2024-08-07 02:37:31

网络接口协议 JSON 解析 Crash 的哪些事的相关文章

iOS之网络数据下载和JSON解析

iOS之网络数据下载和JSON解析 简介 在本文中笔者主要给大家介绍IOS如何利用NSURLConnection从网络上下载数据,如何解析下载下来的JSON数据格式,以及如何显示数据和图片的异步下载显示. 涉及到的知识点: 1.NSURLConnection 异步下载和封装 2.JSON格式和JSON格式解析 3.数据显示和使用SDWebImage异步显示图片 内容 1.网络下载基础知识介绍 什么是网络应用? 需要通过联网进行操作的应用 网络应用的程序结构? c/s结构:即客户端/服务端 常见的

ios 网络数据下载和JSON解析

ios 网络数据下载和JSON解析 简介 在本文中笔者将要给大家介绍ios中如何利用NSURLConnection从网络上下载数据,如何解析下载下来的JSON数据格式,以及如何显示数据和图片的异步下载显示 涉及到得知识: 1.NSURLConnection异步下载和封装 2.JSON格式和JSON格式解析 3.数据显示和使用SDWebImage异步显示图片 内容 1.网络下载基础知识介绍 (1)什么是网络应用? 一般情况下, iPhone的计算机, 照相机不需要从网络上下载数据也能运行, 所以这

Java基础知识强化103:JSON解析框架汇总

1.Gson Gson是Google提供的一个能够将Java对象转换成相应JSON表达形式的一个开源Java类库,当然用Gson也能将JSON字符串转换成与之等价的Java对象.Gson对于任何Java对象都有效,包括那些预先存在没有源代码的对象. 现在已经有一些能将Java对象转换成JSON的开源项目了.但是大多数项目都要求你在类文件中加入Java注解,而当你无法改动源代码的时候这是无法做到的.并且它们也不支持Java泛型.但是Gson却将这两点作为自己非常重要的设计目标. 目标 使用toJs

核心技术篇:6.android网络编程之json解析

前言:好一段时间没写博客了,说最近挺忙的,感觉像是个借口,每天还是同样的24个小时,每天还是同样的5:30就准时下班,每天晚上还是有大量的空余时间...最直接的原因就是,最近堕落了.脑子里也时常会有很多想法浮现,都是些比较实际的想法,但往往就是浮现那一下,心情激动了一下,心里默默告诉自己,有时间就要这么做...好多想法都被一些其它的诱惑给磨灭掉了,要么是打球.要么是看电影.要么是处理一些乱七八糟的事去了.总之,近段时间,花在技术上的时间很少很少,好好反思下. 前段时间,来了一位新疆的客户,提出了

IOS - 网络(HTTP请求、同步请求、异步请求、JSON解析数据)

1 // 2 // ViewController.m 3 // IOS_0129_HTTP请求 4 // 5 // Created by ma c on 16/1/29. 6 // Copyright © 2016年 博文科技. All rights reserved. 7 // 8 9 #import "ViewController.h" 10 #import "MBProgressHUD+MJ.h" 11 12 @interface ViewController

JAVA自已设计JSON解析器

当然,有很多很好的JSON解析的JAR包,比如JSONOBJECT,GSON,甚至也有为我们测试人员而打造的JSONPATH,但我还是自已实现了一下(之前也实现过,现在属于重构). 思想是这样的,以这个JSON串为例:String j = "{\"a\":\"b\",\"c\\\"b\":{\"a\":1},\"d\":[\"a\",{\"a\":

文件与网络、JSON解析

文件与网络.JSON解析   分类: OC语言基础 同步.异步.JSON解析.XML解析 NSData 字节数据存储,二进制存储,苹果中认为字符型和字节型都可以存,即计算机中所有类型的数据,主要用于网络传输数据的缓冲存储 GET请求,只支持255个字符 ,安全性较差,将请求信息附加在超链接上,较方便  POST请求,上传没有大小限制,请求信息在请求体内,在超链接上不能看到,安全性强,缺点:不方便 同步连接:UI “冻结” 异步连接:UI “不冻结” 异步连接,用代理:下载容易造成UI冻结,耗时,

Android数据加载及Json解析——框架版

方法调用 new ApiUser(this).initData(new ApiRequest() { @Override public void onResult(BeanRequest bean) { //如果接口调用不成功,给予提示 if (!bean.isSuccess()) { UtilToast.show(Activitymain.this, bean.getErrInfo(), UtilToast.STYLE_ERROR); } //Json数据解析:BeanInitData 数据实

Qt on Android: http下载与Json解析

百度提供有查询 ip 归属地的开放接口,当你在搜索框中输入一个 ip 地址进行搜索,就会打开由 ip138 提供的百度框应用,你可以在框内直接输入 ip 地址查询.我查看了页面请求,提取出查询 ip 归属地的接口,据此使用 Qt 写了个简单的 ip 归属地查询应用.可以在电脑和 Android 手机上运行.这里使用了百度 API ,特此声明,仅可作为演示使用,不能用作商业目的. 版权所有 foruok,转载请注明出处( http://blog.csdn.net/foruok ). 这个例子会用到