NSDictionary读取数据类型异常问题.

摘要:
NSDictionary读取ID类型。如果是数字,则需要再次转换。这就是问题所在。解决方案就在这里。以下知识点@encoder()用于在此处添加判断实现。为了更好的互操作性,Objective-C的数据类型,甚至用户定义的类型、函数或方法的元类型都可以用ASCII编码。

起因:做网络交互时,经常会使用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

免责声明:文章转载自《NSDictionary读取数据类型异常问题.》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇linux系统编程:自己动手写一个who命令模拟电子电路基础--半导体的基础知识下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

IOS(数据库的应用)

在iPhone的开发过程中常常会用到数据库,而SQLite3是iPhone中支持的数据库。下面简单介绍一下iPhone中SQLite3数据库的用法: SQLite3简介 SQLite3是一个轻量级的数据库,完全使用C语言编写,使用简单方便。它是一个嵌入到程序进程的数据库,和其他一些数据库(MySQL,MS SQL)不同,它没有独立的进程。 1、打开数据库...

iOS 本地存储四种方法

在iOS开发过程中,不管是做什么应用,都会碰到数据保存的问题。将数据保存到本地,能够让程序的运行更加流畅,不会出现让人厌恶的菊花形状,使得用户体验更好。下面介绍⼀一下数据保存的方式: 1.NSKeyedArchiver:采用归档的形式来保存数据,该数据对象需要遵守NSCoding协议,并且该对象对应的类必须提 供encodeWithCoder:和init...

ios 开发之 各种数据类型之间转换 (持续补充)

1.图片转base64串及反转回图片 UIImage图片转成base64字符串: 1 UIImage *_originImage = [UIImage imageNamed:@"full_playlist_hl.png"]; 2 NSData *_data = UIImageJPEGRepresentation(_image, 1.0f);3 NSStri...

解决PHP json_encode() 编码字符中包含<>时,转化为\u003E\u003C

一、PHP json_encode里面经常用到的 JSON_UNESCAPED_UNICODE和JSON_UNESCAPED_SLASHES php格式化json的函数 json_encode($value,$options) 其中有2个比较常用到的参数 JSON_UNESCAPED_UNICODE(中文不转为unicode ,对应的数字 256) J...

应用沙盒(Application Sandbox)

一、应用沙盒目录   应用沙盒包含多个目录: 1、应用程序包:(application bundle):包含所有的资源文件和可执行文件,并且是只读目录。 2、Library/Preferences/:存放所有的偏好设置(preferences),iOS的Setting(设置)应用会在该目录中查找应用的设置信息。通过NSUserDefaults类,可以存取L...

iOS平台下cookie的使用

iOS平台下cookie的使用 首先,先介绍下iOS对cookie的操作的两个类: 帖子来源于:http://blog.csdn.net/chun799/article/details/17206907 1. NSHTTPCookie  2. NSHTTPCookieStorage NSHTTPCookie对象代表一个HTTP cookie。 这是一个不...