在iOS开发过程中经常需要与服务器进行数据通讯,Json就是一种常用的高效简洁的数据格式。
JSON建构有两种结构:
json简单说就是javascript中的对象和数组,所以这两种结构就是对象和数组2种结构,通过这两种结构可以表示各种复杂的结构
1、对象:对象在js中表示为“{}”扩起来的内容,数据结构为 {key:value,key:value,...}的键值对的结构,在面向对象的语言中,key为对象的属性,value为对应的属性值,所以很容易理解,取值方法为对象.key 获取属性值,这个属性值的类型可以是 数字、字符串、数组、对象几种。
2、数组:数组在js中是中括号“[]”扩起来的内容,数据结构为 ["java","javascript","vb",...],取值方式和所有语言中一样,使用索引获取,字段值的类型可以是数字、字符串、数组、对象几种。
经过对象、数组2种结构就可以组合成复杂的数据结构了。
问题现象
但是几个项目下来一直遇到一个坑爹的问题,程序在获取某些数据之后莫名崩溃。其实很早就发现了原因:由于服务器的数据库中有些字段为空,然后以Json形式返回给客户端时就会出现这样的数据:
"somevalue":null
通过JsonKit 这个第三方库解析出来的数据就成了
somevalue = "<null>";
这个数据类型不是nil 也不是 String。 解析成对象之后,如果直接向这个对象发送消息(eg:length,count 等等)就会直接崩溃。提示错误为:
-[NSNull length]: unrecognized selector sent to instance 0x388a4a70
解决方法
其实一直没有找到完美的解决办法,坑了我很久。
1、最开始的解决方法就是为了应付当前遇到的崩溃,看看哪个字段可能为空,那么就对该字段使用前进行判断,通过崩溃时的错误提示可以看出,这样的字段解析成的对象是 NSNull 类型的,所以可以直接判断是不是此类型:
if (![isKindOfClass:[NSNull class]]){xxxxxxx;}
因为字段实在太多,就找一个补一个。
2、后来想彻底解决这问题,就打算从数据源下手,其实应该可以用正则表达式匹配这个null ,然后进行替换,奈何正则是我的硬伤啊。于是就相出了一个山寨方法:字符串匹配。在获取到服务器返回的Json时,返回结果时string对象,于是就先替换 null 为 为空字符””,然后再解析。
json = [jsonStr stringByReplacingOccurrencesOfString:@":null" withString:@":\"\""];
这个方法本来很奏效,但是我这里的服务器返回极不简洁,各种垃圾数据(不吐槽这了)。。。反正这样会导致json无法解析了。
3、最后没有办法,只能在解析的时候下手,把是NSNull 类型的值替换成nil。 一般就写个tool方法,然后解析时调用。但是嫌太麻烦,就想弄写个宏,通过搜索惊奇的发现宏也是可以有返回值的,结果如下:
#define VerifyValue(value)\
({id tmp;\
if ([value isKindOfClass:[NSNull class]])\
tmp = nil;\
else\
tmp = value;\
tmp;\
})\
宏里的最后一句语句便是返回值。然后在解析数据时调用宏:
contact.contactPhone = VerifyValue(contactDic[@"send_ContactPhone"]);
4、如果你使用AFNetwork 这个库做网络请求的话,可以用以下代码,自动帮你去掉这个讨厌的空值
self.removesKeysWithNullValues = YES;
5、终极方案
终于找到了一劳永逸的方案,牛逼的老外写了一个Category,叫做NullSafe ,在运行时操作,把这个讨厌的空值置为nil,而nil是安全的,可以向nil对象发送任何message而不会奔溃。这个category使用起来非常方便,只要加入到了工程中就可以了,你其他的什么都不用做,对,就是这么简单。详细的请去Github上查看;
本文向大家介绍iOS中nil、Nil、NULL、NSNull详解,包括了iOS中nil、Nil、NULL、NSNull详解的使用技巧和注意事项,需要的朋友参考一下 ObjC 里面的几个空值符号经常会差点把我搞死,这些基础的东西一点要弄清楚才行,以提高码农的基本素质。 nil nil 是 ObjC 对象的字面空值,对应 id 类型的对象,或者使用 @interface 声明的 ObjC 对象。 例如
本文向大家介绍IOS json 解析遇到错误问题解决办法,包括了IOS json 解析遇到错误问题解决办法的使用技巧和注意事项,需要的朋友参考一下 概要: Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn't be completed. (Cocoa error 3840.)" (Unescaped control ch
问题内容: 我正在为现有网站创建一个应用程序。他们目前具有以下格式的JSON: 他们使用Java脚本将\字符转义后解析。 我的问题是当我使用以下命令在iOS中解析它时: 并这样做: 而不是我得到了对象。 该网站已经投入生产,所以我不能要求他们更改现有结构以返回适当的对象。对他们来说,这将是很多工作。 因此,在他们改变基础结构之前,有什么方法可以使它们像在它们上面一样地工作吗? 任何帮助/建议对我都
本文向大家介绍详解Nginx 出现 403 Forbidden 的解决办法,包括了详解Nginx 出现 403 Forbidden 的解决办法的使用技巧和注意事项,需要的朋友参考一下 Nginx 也是当前流行的一款 轻量级服务器 在日常使用中呢 也会出现一些问题 今天 学习君 在安装配置Nginx的时候就出现了 403 Forbindden 的被禁止访问的错误 网上搜索之后呢 完美解决
本文向大家介绍解决golang json解析出现值为空的问题,包括了解决golang json解析出现值为空的问题的使用技巧和注意事项,需要的朋友参考一下 我是通过beego框架,将请求过来的json进行解析,并将值保存在结构体中 其中 UpdateCommentRequestData的结构是这样的 common.request的结构是这样的 我使用1中的代码进行解析,发现request.Id的值
本文向大家介绍详解Linux下出现permission denied的解决办法,包括了详解Linux下出现permission denied的解决办法的使用技巧和注意事项,需要的朋友参考一下 Permission denied: 出现的原因的是:没有权限进行读、写、创建文件、删除文件等操作。 解决方法:输入命令 sudo chmod -R 777 /工作目录, 例如:sudo chmode -R