我们在处理数据库接口的过程中,如果数据中出现null,我们是没法处理的。我在使用NSUserDaults保存后,出现崩溃。

null产生原因

null是后台在处理数据的时候,如果没有设置value值,数据库默认填充的值。

解决办法

  • 数据库做处理
  • 本地做删除null处理

本地做删除null处理

如果是数据库做处理的话,可以在数据库中,将未设置的value填充为" "即可。

如果是本地处理的话,我个人是通过添加类别来达到效果的。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- (NSDictionary *)deleteNull{
 
NSMutableDictionary *mutableDic = [[NSMutableDictionary alloc] init];
for (NSString *keyStr in self.allKeys) {
 
    if ([[self objectForKey:keyStr] isEqual:[NSNull null]]) {
 
        [mutableDic setObject:@"" forKey:keyStr];
    }
    else{
 
        [mutableDic setObject:[self objectForKey:keyStr] forKey:keyStr];
    }
}
return mutableDic;
}
  

-------------------------------------------------------------------------------------------------

在iOS开发过程中经常需要与服务器进行数据通讯,Json就是一种常用的高效简洁的数据格式。

问题现象

但是几个项目下来一直遇到一个坑爹的问题,程序在获取某些数据之后莫名崩溃。其实很早就发现了原因:由于服务器的数据库中有些字段为空,然后以Json形式返回给客户端时就会出现这样的数据:

1
"somevalue":null

通过JsonKit 这个第三方库解析出来的数据就成了

1
somevalue = "<null>";

这个数据类型不是nil 也不是 String。 解析成对象之后,如果直接向这个对象发送消息(eg:length,count 等等)就会直接崩溃。提示错误为:

1
 -[NSNull length]: unrecognized selector sent to instance 0x388a4a70

解决方法

其实一直没有找到完美的解决办法,坑了我很久。

1、最开始的解决方法就是为了应付当前遇到的崩溃,看看哪个字段可能为空,那么就对该字段使用前进行判断,通过崩溃时的错误提示可以看出,这样的字段解析成的对象是 NSNull 类型的,所以可以直接判断是不是此类型:

1
 if (![isKindOfClass:[NSNull class]]){xxxxxxx;}

因为字段实在太多,就找一个补一个。

2、后来想彻底解决这问题,就打算从数据源下手,其实应该可以用正则表达式匹配这个null ,然后进行替换,奈何正则是我的硬伤啊。于是就相出了一个山寨方法:字符串匹配。在获取到服务器返回的Json时,返回结果时string对象,于是就先替换 null 为 为空字符””,然后再解析。

1
json = [jsonStr  stringByReplacingOccurrencesOfString:@":null" withString:@":\"\""];

这个方法本来很奏效,但是我这里的服务器返回极不简洁,各种垃圾数据(不吐槽这了)。。。反正这样会导致json无法解析了。

3、最后没有办法,只能在解析的时候下手,把是NSNull 类型的值替换成nil。 一般就写个tool方法,然后解析时调用。但是嫌太麻烦,就想弄写个宏,通过搜索惊奇的发现宏也是可以有返回值的,结果如下:

1
2
3
4
5
6
7
8
#define VerifyValue(value)\
({id tmp;\
if ([value isKindOfClass:[NSNull class]])\
tmp = nil;\
else\
tmp = value;\
tmp;\
})\

宏里的最后一句语句便是返回值。然后在解析数据时调用宏:

1
contact.contactPhone = VerifyValue(contactDic[@"send_ContactPhone"]);

4、如果你使用AFNetwork 这个库做网络请求的话,可以用以下代码,自动帮你去掉这个讨厌的空值

1
self.removesKeysWithNullValues = YES;

5、终极方案
终于找到了一劳永逸的方案,牛逼的老外写了一个Category,叫做NullSafe ,在运行时操作,把这个讨厌的空值置为nil,而nil是安全的,可以向nil对象发送任何message而不会奔溃。这个category使用起来非常方便,只要加入到了工程中就可以了,你其他的什么都不用做,对,就是这么简单。详细的请去Github上查看;
https://github.com/nicklockwood/NullSafe

---------------------------------------------------------------------

解决NSArray和NSDictionary中含有null时  writeToFile 失败的问题
@implementation NSArray(Plist)

-(BOOL)writeToPlistFile:(NSString*)filename{
NSData * data = [NSKeyedArchiver archivedDataWithRootObject:self];
NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString * documentsDirectory = [paths objectAtIndex:];
NSString * path = [documentsDirectory stringByAppendingPathComponent:filename];
BOOL didWriteSuccessfull = [data writeToFile:path atomically:YES];
return didWriteSuccessfull;
} +(NSArray*)readFromPlistFile:(NSString*)filename{
NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString * documentsDirectory = [paths objectAtIndex:];
NSString * path = [documentsDirectory stringByAppendingPathComponent:filename];
NSData * data = [NSData dataWithContentsOfFile:path];
return [NSKeyedUnarchiver unarchiveObjectWithData:data];
} @end //needs to be set for implementation
 

相关链接:

删除字典中的null

关于Json中null的问题以及宏的返回值

解决NSArray和NSDictionary中含有null时 writeToFile 失败的问题

iOS请求服务器数据去空NSNull的更多相关文章

  1. 关于纯xmlhttprequest请求服务器数据

    今天我们的web技术已经相当的完善, 各种前端框架如jquery或者再深一点的工具APIcloud 的使用极大的方便了我们的开发工作. 今天我要分享一个纯javascript的方式来解决请求服务器数据 ...

  2. Ajax在jQuery中的应用(加载异步数据、请求服务器数据)

    加载异步数据 jQuery中的load()方法 load(url,[data],[callback]) url:被加载的页面地址 [data]:可选项表示发送到服务器的数据,其格式为 key/valu ...

  3. IOS 请求服务器的方式

    IOS 中请求服务器的方式主要有Get 和Post . Get :[1]向服务器发索取数据的一种请求; [2]获取信息,而不是修改信息,类似数据库查询功能一样,数据不会被修改;请求的参数会跟在url后 ...

  4. app请求服务器数据方法1-HttpUrlConnection

    1. 实例化URL对象 首先第一步实例化一个URL对象,传入参数为请求的数据的网址. URL url = new URL("http://www.imooc.com/api/teacher? ...

  5. APP请求服务器数据-HttpUrlConnection

    1. 实例化URL对象 首先第一步实例化一个URL对象,传入参数为请求的数据的网址. URL url = new URL("http://www.imooc.com/api/teacher? ...

  6. java ajax长连接请求服务器数据

    Servlet 3.0笔记之异步请求Comet推送长轮询(long polling)篇 Comet另一种形式为长轮询(long polling),客户端会与服务器建立一个持久的连接,直到服务器端有数据 ...

  7. 使用ajax()方法加载服务器数据

    使用ajax()方法加载服务器数据 使用ajax()方法是最底层.功能最强大的请求服务器数据的方法,它不仅可以获取服务器返回的数据,还能向服务器发送请求并传递数值,它的调用格式如下: jQuery.a ...

  8. iOS服务器数据请求"汉字编码"问题

    下面记录一下数据请求问题: 1.不知道大家有木有遇到过,当数据请求的URL带有汉字的时候,请求数据肯定会报404错误,也就是参数或者是接口URL错误<虽然说404,500等错误一般都是服务器问题 ...

  9. iOS - NetRequest 网络数据请求

    1.网络请求 1.1 网络通讯三要素 1.IP 地址(主机名): 网络中设备的唯一标示.不易记忆,可以用主机名(域名). 1) IP V4: 0~255.0~255.0~255.0~255 ,共有 2 ...

随机推荐

  1. SharePoint 如何找到List的Template ID

    在我们添加Ribbon操作,或者对特定模板进行操作的时候,经常需要ListTemplate的数值,我们经常需要搜索各种网页,来查找匹配的ListTemplate值,其实,有个比较简便的方法. 像定义R ...

  2. How to Get SharePoint Client Context in SharePoint Apps (Provider Hosted / SharePoint Access ) in CSOM (Client Side Object Model)

    http://www.codeproject.com/Articles/581060/HowplustoplusGetplusSharePointplusClientplusContex Downlo ...

  3. 转:使用Nlog记录日志到数据库

    原文:http://www.cnblogs.com/Gyoung/archive/2012/10/18/2729613.html Nlog是一个很不错的.NET日志记录组件,它可以将日志输出到控件台, ...

  4. IOS 网络浅析 (二 网络异步请求)

    学习网络,无论是C/S还是B/S首要的当然是向服务器发送请求,并得到响应,么有请求没有响应,那就不叫做网络了. 这边文章向大家介绍境界一下网路异步请求. *大家不要觉得我写的知识点太零散,我只是想给大 ...

  5. 【转】IOS屏幕旋转与View的transform属性之间的关系,比较底层

    iTouch,iPhone,iPad设置都是支持旋转的,如果我们的程序能够根据不同的方向做出不同的布局,体验会更好. 如何设置程序支持旋转呢,通常我们会在程序的info.plist中进行设置Suppo ...

  6. 自定义组件 -- android联系人

    在android开发中,常常有联系人页面,在这篇和大家分享一下项目中刚刚添加的联系人页面,代码直接从项目中提取出来,没有太多时间修改:使用 StickyListHeaders-master 开源项目及 ...

  7. IOS开发之实现App消息推送(最新)

    好久没有写过博客啦,今天就由本菜鸟给大家做一个简单的IOSApp消息推送教程吧!一切从0开始,包括XCode6, IOS8, 以及苹果开发者中心最新如何注册应用,申请证书以及下载配置概要文件,相信很多 ...

  8. 使用eclipse遇到问题:the-package-collides-with-a-type

    相似问题:http://stackoverflow.com/questions/12236909/the-package-collides-with-a-type

  9. mysql高可用之LVS + KEEPALIVE + MYSQL

    1.架构图 注意 (一)   Mysql需要把bind-address的配置去掉,否则无法实现虚拟ip访问 (二)   关闭所有linux防火墙:/sbin/iptables –F(可能没用) (三) ...

  10. Asp.Net实现WebApi跨域 (非MVC)

    目前WebApi在使用上大部分都是跟MVC组合的,而且使用起来也确实十分便利. 但有时候我们也需要在WebForm中使用WebApi,二者还是有一定区别的. 首先看下结构  ①ApiControlle ...