标签:
起因:做网络交互时,经常会使用JSON作为数据的承载体,本来是件好事,但是用多了,发现iOS侧偶尔会出现异常,几经比较发现是服务器给的数据有问题,该给INT的给按照STR给了,
服务器能做动态更新,可客户端不行啊,怎么办?NSDictionary读到的是id类型,如果是数字,需要再转换下才可以,出问题就在这里.那解决思路就在这里,在这里增加判断
实现
用到了以下几个知识点
@encode()
为了更好的互操作性,Objective-C 的数据类型,甚至自定义类型、函数或方法的元类型,都可以使用 ASCII 编码。@encode(aType) 可以返回该类型的 C 字符串(char *)的表示
[obj objcType]
获取obj对象的对象类型的C编码字符串.
OK,比较就好.
#import <Foundation/Foundation.h> /* 改造 1 增加读取数据时,如果没有键值,返回默认值的动作. 2 屏蔽无键值时字典异常的问题. 3 增加双字段类型CGPoint的读取动作. 4 增加底层判断实际数据类型与读取动作不匹配导致的问题. */ @interface NSDictionary (ReadAdditions) - (BOOL)getBoolValueForKey:(NSString *)key defaultValue:(BOOL)defaultValue; - (NSInteger)getIntValueForKey:(NSString *)key defaultValue:(NSInteger)defaultValue; - (float)getFloatValueForKey:(NSString *)key defaultValue:(float)defaultValue; - (time_t)getTimeValueForKey:(NSString *)key defaultValue:(time_t)defaultValue; - (long long)getLongLongValueValueForKey:(NSString *)key defaultValue:(long long)defaultValue; - (NSString *)getStringValueForKey:(NSString *)key defaultValue:(NSString *)defaultValue; - (id)getValueForKey:(NSString*)key defaultValue:(id)defalueValue; - (CGPoint)getPointForKey:(NSString*)xKey yKey:(NSString*)yKey defaultValue:(CGPoint)defaultValue; @end
实现
#import "NSDictionaryReadAdditions.h" typedef NS_ENUM(NSUInteger, PODTYPE) { PT_UNKNOWN = -1, PT_INT = 0, PT_FLOAT, PT_DOUBLE, PT_BOOL, PT_INT64, PT_STRING, PT_ARRAY, }; @implementation NSDictionary (ReadAdditions) -(PODTYPE)getPodType:(id)obj { if([obj isKindOfClass:[NSNumber class]]) { const char * pObjCType = [((NSNumber*)obj) objCType]; if (strcmp(pObjCType, @encode(BOOL)) == 0) { return PT_BOOL; } if (strcmp(pObjCType, @encode(int)) == 0) { return PT_INT; } if (strcmp(pObjCType, @encode(float)) == 0) { return PT_FLOAT; } if (strcmp(pObjCType, @encode(double)) == 0) { return PT_DOUBLE; } } return PT_UNKNOWN; } -(BOOL)isPodIntObj:(id)obj { if (nil == obj) return NO; if([obj isKindOfClass:[NSNumber class]]) { const char * pObjCType = [((NSNumber*)obj) objCType]; if (strcmp(pObjCType, @encode(int)) == 0) { return YES; } } return NO; } -(BOOL)isPodBoolObj:(id)obj { if (nil == obj) return NO; if([obj isKindOfClass:[NSNumber class]]) { const char * pObjCType = [((NSNumber*)obj) objCType]; if (strcmp(pObjCType, @encode(BOOL)) == 0) { return YES; } } return NO; } -(BOOL)isPodFloatObj:(id)obj { if (nil == obj) return NO; if([obj isKindOfClass:[NSNumber class]]) { const char * pObjCType = [((NSNumber*)obj) objCType]; if (strcmp(pObjCType, @encode(float)) == 0) { return YES; } } return NO; } -(BOOL)isPodInt64Obj:(id)obj { if (nil == obj) return NO; if([obj isKindOfClass:[NSNumber class]]) { const char * pObjCType = [((NSNumber*)obj) objCType]; if (strcmp(pObjCType, @encode(long long)) == 0) { return YES; } } return NO; } -(BOOL)isNSTypeObj:(id)obj andType:(Class)objClass { if (nil == obj || nil == objClass) return NO; if ([obj isMemberOfClass:objClass]) { return YES; } return NO; } - (BOOL)getBoolValueForKey:(NSString *)key defaultValue:(BOOL)defaultValue { id obj = [self getValueForKey:key defaultValue:nil]; if (nil == obj) { return defaultValue; } if ([self isPodBoolObj:obj]) return [obj boolValue]; else { NSLog(@"警告[%s],数据对象类型不符:%@",__FUNCTION__, key); } return defaultValue; } - (NSInteger)getIntValueForKey:(NSString *)key defaultValue:(NSInteger)defaultValue { id obj = [self getValueForKey:key defaultValue:nil]; if (nil == obj) { return defaultValue; } if ([self isPodIntObj:obj]) return [obj integerValue]; else { NSLog(@"警告[%s],数据对象类型不符:%@",__FUNCTION__, key); } return defaultValue; } - (float)getFloatValueForKey:(NSString *)key defaultValue:(float)defaultValue { id obj = [self getValueForKey:key defaultValue:nil]; if (nil == obj) { return defaultValue; } if ([self isPodFloatObj:obj]) return [obj floatValue]; else { NSLog(@"警告[%s],数据对象类型不符:%@",__FUNCTION__, key); } return defaultValue; } - (time_t)getTimeValueForKey:(NSString *)key defaultValue:(time_t)defaultValue { NSString *stringTime = [self objectForKey:key]; if ((id)stringTime == [NSNull null]) { stringTime = @""; } struct tm created; time_t now; time(&now); if (stringTime) { if (strptime([stringTime UTF8String], "%a %b %d %H:%M:%S %z %Y", &created) == NULL) { strptime([stringTime UTF8String], "%a, %d %b %Y %H:%M:%S %z", &created); } return mktime(&created); } return defaultValue; } - (long long)getLongLongValueValueForKey:(NSString *)key defaultValue:(long long)defaultValue { id obj = [self getValueForKey:key defaultValue:nil]; if (nil == obj) { return defaultValue; } if ([self isPodInt64Obj:obj]) return [obj longLongValue]; else { NSLog(@"警告[%s],数据对象类型不符:%@",__FUNCTION__, key); } return defaultValue; } - (NSString *)getStringValueForKey:(NSString *)key defaultValue:(NSString *)defaultValue { id obj = [self getValueForKey:key defaultValue:nil]; if (nil == obj) { return defaultValue; } if ([self isNSTypeObj:obj andType:[NSString class]]) return obj; else { NSLog(@"警告[%s],数据对象类型不符:%@",__FUNCTION__, key); } return defaultValue; return [self objectForKey:key] == nil || [self objectForKey:key] == [NSNull null] ? defaultValue : [self objectForKey:key]; } -(id)getValueForKey:(NSString*)key defaultValue:(id)defaultValue { return [self objectForKey:key] == nil || [self objectForKey:key] == [NSNull null] ? defaultValue : [self objectForKey:key]; } -(CGPoint)getPointForKey:(NSString*)xKey yKey:(NSString*)yKey defaultValue:(CGPoint)defaultValue { CGPoint tmp = CGPointZero; tmp.x = [self getFloatValueForKey:xKey defaultValue:defaultValue.x]; tmp.y = [self getFloatValueForKey:yKey defaultValue:defaultValue.y]; return tmp; } @end
标签:
原文地址:http://www.cnblogs.com/decwang/p/4705199.html