返回值重载,安全访问JSON反序列化生成的NSDictionary

24 篇文章 0 订阅
19 篇文章 0 订阅

    由JSON反序列化生成的NSDictionary,我们在解析时需要按照固定格式将数据读取出来。如果由于某些原因,我们拿到的数据格式变化了,而我们并不知道,仍然按照之前的固定格式读取,那么很有可能发生崩溃。

    例如,

    对于JSON串

NSString * jsonStr = @"{\"a\":[1,2,3]}";
反序列化成NSDictionary后,这样解析数据

NSDictionary * dic = [ jsonStr 反序列化];
NSArray * arr = dic[@"a"];
for (NSNumber * n in arr)
{
    ...
}

如果JSON串发生变化,变成

NSString * jsonStr = @"{\"a\":123}";

而解析代码保持不变,那么,崩溃将发生在for语句那一行。原因是@"a"的值由数组变成了字符串

NSDictionary * dic = [ jsonStr 反序列化];
NSArray * arr = dic[@"a"];
for (NSNumber * n in arr)   //崩溃  arr不再是NSarry类型
{
    ...
}

如果在for语句前加个判断,崩溃会避免


if ([arr isKindOfClass:[NSArray class]])
{}

而,我们要做的就是利用C++的操作符重载和隐式转换,实现上面的判断,如果类型不正确就返回nil;幸好,Objective-C中,对nil发送方法是安全。

首先,封装一个SafeNSDictionaryValue类,重载NSAarr *的转换

class SafeNSDictionaryValue
{
public:
    SafeNSDictionaryValue(NSObject* value):_value(value){}
    SafeNSDictionaryValue(const SafeNSDictionaryValue &v)
    {
        _value = v._value;
    }
    SafeNSDictionaryValue & operator=(const SafeNSDictionaryValue &v)
    {
        if (this != &v)
        {
            _value = v._value;
        }
        return *this;
    }
    
    operator NSArray *() //重载NSAarr *的转换
    {
        if ([_value isKindOfClass:[NSArray class]])
        {
            return (NSArray*)_value;
        }
        return nil;
    }
private:
    NSObject * _value;
};

对SafeNSDictionaryValue类,可以这样放心使用

NSObject *obj = xxxxx;
SafeNSDictionaryValue value(obj);
NSArray * arr = value;//这里会触发SafeNSDictionaryValue的隐式转换
for(id elem in arr) //不会崩溃啦

到这里,主要工作已经完成了,为了方便,我们还需要封装一个SafeNSDictionary,配合SafeNSDictionaryValue

class SafeNSDictionary
{
public:
    SafeNSDictionary(id dic)
    {
        if ([dic isKindOfClass:[NSDictionary class]])
        {
            _dic = dic;
        }
        else
        {
            _dic = nil;
        }
    }
    
    SafeNSDictionary(const SafeNSDictionary &v)
    {
        _dic = v._dic;
    }
    
    SafeNSDictionary & operator=(const SafeNSDictionary &v)
    {
        if (this != &v)
        {
            _dic = v._dic;
        }
        return *this;
    }
    
    
    SafeNSDictionaryValue operator[](NSString * key) //重载操作符[]
    {
        return _dic[key];
    }
    
private:
    NSDictionary * _dic;
};

SafeNSDictionaryValue 和 SafeNSDictionary配合使用

        NSString * jsonStr = @"{\"a\":[1,2,3]}";
        SafeNSDictionary dic = [jsonStr objectFromJSONString]; //自行引入JSONKit库
        NSArray * arr = dic[@""];
        for (NSNumber * number in arr)
        {
            
        }

好了,对于NSString * ,NSNumber * , NSDictionary * ,按照NSArray*方式补全代码

完整版代码:

//
//  SafeNSDictionary.h  zxs.zl

#pragma once
#import <Foundation/Foundation.h>

class SafeNSDictionary;

class SafeNSDictionaryValue
{
public:
    SafeNSDictionaryValue(NSObject* value);
    SafeNSDictionaryValue(const SafeNSDictionaryValue &v);
    SafeNSDictionaryValue & operator=(const SafeNSDictionaryValue &v);
    
    char charValue();
    unsigned char unsignedCharValue();
    short shortValue();
    unsigned short unsignedShortValue();
    int intValue();
    unsigned int unsignedIntValue();
    long longValue();
    unsigned long unsignedLongValue();
    long long longLongValue();
    unsigned long long unsignedLongLongValue();
    float floatValue();
    double doubleValue();
    BOOL boolValue();
    NSInteger integerValue();
    NSUInteger unsignedIntegerValue();
    
    operator NSString *();
    operator NSArray *();
    operator NSDictionary*();
    operator SafeNSDictionary();
    operator NSNumber *();
private:
    NSObject * _value;
};

class SafeNSDictionary
{
public:
    SafeNSDictionary(NSDictionary* dic);
    SafeNSDictionary(const SafeNSDictionary &v);
    SafeNSDictionary & operator=(const SafeNSDictionary &v);
    SafeNSDictionaryValue operator[](NSString* key);
    
    operator BOOL();
    operator NSDictionary *();
private:
    NSDictionary * _dic;
};

//
//  SafeNSDictionary.mm  zxs.zl

#include "SafeNSDictionary.h"


SafeNSDictionaryValue::SafeNSDictionaryValue(NSObject* value):_value(value){}

SafeNSDictionaryValue::SafeNSDictionaryValue(const SafeNSDictionaryValue &v)
{
    _value = v._value;
}

SafeNSDictionaryValue & SafeNSDictionaryValue::operator=(const SafeNSDictionaryValue &v)
{
    if (this != &v)
    {
        _value = v._value;
    }
    return *this;
}

char SafeNSDictionaryValue::charValue()
{
    if ([_value respondsToSelector:@selector(charValue)])
    {
        return [(NSNumber*)_value charValue];
    }
    return 0;
}
unsigned char SafeNSDictionaryValue::unsignedCharValue()
{
    if ([_value respondsToSelector:@selector(unsignedCharValue)])
    {
        return [(NSNumber*)_value unsignedCharValue];
    }
    return 0;
}
short SafeNSDictionaryValue::shortValue()
{
    if ([_value respondsToSelector:@selector(shortValue)])
    {
        return [(NSNumber*)_value shortValue];
    }
    return 0;
}
unsigned short SafeNSDictionaryValue::unsignedShortValue()
{
    if ([_value respondsToSelector:@selector(unsignedShortValue)])
    {
        return [(NSNumber*)_value unsignedShortValue];
    }
    return 0;
}
int SafeNSDictionaryValue::intValue()
{
    if ([_value respondsToSelector:@selector(intValue)])
    {
        return [(NSNumber*)_value intValue];
    }
    return 0;
}
unsigned int SafeNSDictionaryValue::unsignedIntValue()
{
    if ([_value respondsToSelector:@selector(unsignedIntValue)])
    {
        return [(NSNumber*)_value unsignedIntValue];
    }
    return 0;
}
long SafeNSDictionaryValue::longValue()
{
    if ([_value respondsToSelector:@selector(longValue)])
    {
        return [(NSNumber*)_value longValue];
    }
    return 0;
}
unsigned long SafeNSDictionaryValue::unsignedLongValue()
{
    if ([_value respondsToSelector:@selector(unsignedLongValue)])
    {
        return [(NSNumber*)_value unsignedLongValue];
    }
    return 0;
}
long long SafeNSDictionaryValue::longLongValue()
{
    if ([_value respondsToSelector:@selector(longLongValue)])
    {
        return [(NSNumber*)_value longLongValue];
    }
    return 0;
}
unsigned long long SafeNSDictionaryValue::unsignedLongLongValue()
{
    if ([_value respondsToSelector:@selector(unsignedLongLongValue)])
    {
        return [(NSNumber*)_value unsignedLongLongValue];
    }
    return 0;
}
float SafeNSDictionaryValue::floatValue()
{
    if ([_value respondsToSelector:@selector(floatValue)])
    {
        return [(NSNumber*)_value floatValue];
    }
    return 0;
}
double SafeNSDictionaryValue::doubleValue()
{
    if ([_value respondsToSelector:@selector(doubleValue)])
    {
        return [(NSNumber*)_value doubleValue];
    }
    return 0;
}
BOOL SafeNSDictionaryValue::boolValue()
{
    if ([_value respondsToSelector:@selector(boolValue)])
    {
        return [(NSNumber*)_value boolValue];
    }
    return NO;
}
NSInteger SafeNSDictionaryValue::integerValue()
{
    if ([_value respondsToSelector:@selector(integerValue)])
    {
        return [(NSNumber*)_value integerValue];
    }
    return 0;
}
NSUInteger SafeNSDictionaryValue::unsignedIntegerValue()
{
    if ([_value respondsToSelector:@selector(unsignedIntegerValue)])
    {
        return [(NSNumber*)_value unsignedIntegerValue];
    }
    return 0;
}

SafeNSDictionaryValue::operator NSString *()
{
    if ([_value isKindOfClass:[NSString class]])
    {
        return (NSString*)_value;
    }
    return nil;
}
SafeNSDictionaryValue::operator NSArray *()
{
    if ([_value isKindOfClass:[NSArray class]])
    {
        return (NSArray*)_value;
    }
    return nil;
}
SafeNSDictionaryValue::operator NSDictionary*()
{
    if ([_value isKindOfClass:[NSDictionary class]])
    {
        return (NSDictionary*)_value;
    }
    return nil;
}
SafeNSDictionaryValue::operator SafeNSDictionary()
{
    if ([_value isKindOfClass:[NSDictionary class]])
    {
        return (NSDictionary*)_value;
    }
    return nil;
}

SafeNSDictionaryValue::operator NSNumber *()
{
    if ([_value isKindOfClass:[NSNumber class]])
    {
        return (NSNumber*)_value;
    }
    return nil;
}

SafeNSDictionary::SafeNSDictionary(NSDictionary* dic)
{
    if ([dic isKindOfClass:[NSDictionary class]])
    {
        _dic = dic;
    }
    else
    {
        _dic = nil;
    }
}

SafeNSDictionary::SafeNSDictionary(const SafeNSDictionary &v)
{
    _dic = v._dic;
}

SafeNSDictionary & SafeNSDictionary::operator=(const SafeNSDictionary &v)
{
    if (this != &v)
    {
        _dic = v._dic;
    }
    return *this;
}

SafeNSDictionaryValue SafeNSDictionary::operator[](NSString* key)
{
    if (key)
    {
        return _dic[key];
    }
    else
    {
        return nil;
    }
}

SafeNSDictionary::operator NSDictionary *()
{
    return _dic;
}
SafeNSDictionary::operator BOOL()
{
    return [_dic isKindOfClass:[NSDictionary class]];
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值