您的位置:首页 > Web前端 > JavaScript

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

2016-02-24 10:42 627 查看
由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]];
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: