zoukankan      html  css  js  c++  java
  • NSDictionary读取数据类型异常问题.

    起因:做网络交互时,经常会使用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
    
  • 相关阅读:
    Windows PowerShell 2.0之进程管理
    PowerShell 2.0远程管理之交互式远程线程
    PowerShell 2.0解析、格式化及显示远程输出
    PowerShell 2.0语言远程管理之理解线程配置
    PowerShell 2.0远程管理之隐式远程管理
    PowerShell 2.0如何将远程线程保存在本地
    Windows PowerShell 2.0之服务管理
    PowerShell 2.0远程管理开发使用CredSSP处理多跳授权
    通过PowerShell操作事件日志
    (译)Silverlight教程第七部分: 使用控件模板定制控件的观感
  • 原文地址:https://www.cnblogs.com/decwang/p/4705199.html
Copyright © 2011-2022 走看看