返回值重载,安全访问JSON反序列化生成的NSDictionary
2016-02-24 10:42
627 查看
由JSON反序列化生成的NSDictionary,我们在解析时需要按照固定格式将数据读取出来。如果由于某些原因,我们拿到的数据格式变化了,而我们并不知道,仍然按照之前的固定格式读取,那么很有可能发生崩溃。
例如,
对于JSON串
如果JSON串发生变化,变成
而解析代码保持不变,那么,崩溃将发生在for语句那一行。原因是@"a"的值由数组变成了字符串
如果在for语句前加个判断,崩溃会避免
而,我们要做的就是利用C++的操作符重载和隐式转换,实现上面的判断,如果类型不正确就返回nil;幸好,Objective-C中,对nil发送方法是安全。
首先,封装一个SafeNSDictionaryValue类,重载NSAarr *的转换
对SafeNSDictionaryValue类,可以这样放心使用
到这里,主要工作已经完成了,为了方便,我们还需要封装一个SafeNSDictionary,配合SafeNSDictionaryValue
SafeNSDictionaryValue 和 SafeNSDictionary配合使用
好了,对于NSString * ,NSNumber * , NSDictionary * ,按照NSArray*方式补全代码
完整版代码:
例如,
对于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]]; }
相关文章推荐
- JavaScript中Object.prototype.toString方法的原理
- json sort
- JavaScript判断变量是否为数组的方法(Array)
- javascript小实例,实现99乘法表及隔行变色
- 教你用javascript实现随机标签云
- Collection+JSON 文档
- 实现OC与JS的交互
- js实现图片上传预览
- 浅谈使用Fiddler工具发送post请求(带有json数据)以及get请求(Header方式传参)
- javascript 对象遍历
- js Ajax跨域请求
- js排序和查找
- javascript 数组去重
- javascript parseInt函数详解
- 使用js获取表单中各个name的值
- JSONP--解决ajax跨域问题
- jsp日期控件My97DatePicker的使用
- js时间处理
- Javascript的正则表达式
- JS判断页面是否加载完成