返回值重載,安全訪問JSON反序列化生成的NSDictionary

    由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]];
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章