iOS解析json中null終極解決方案

我的博客原文地址

在iOS開(kāi)發(fā)過(guò)程中經(jīng)常需要與服務(wù)器進(jìn)行數(shù)據(jù)通訊,Json就是一種常用的高效簡(jiǎn)潔的數(shù)據(jù)格式。

問(wèn)題現(xiàn)象

但是幾個(gè)項(xiàng)目下來(lái)一直遇到一個(gè)坑爹的問(wèn)題,程序在獲取某些數(shù)據(jù)之后莫名崩潰。其實(shí)很早就發(fā)現(xiàn)了原因:由于服務(wù)器的數(shù)據(jù)庫(kù)中有些字段為空,然后以Json形式返回給客戶端時(shí)就會(huì)出現(xiàn)這樣的數(shù)據(jù):

"somevalue":null

通過(guò)JsonKit 這個(gè)第三方庫(kù)解析出來(lái)的數(shù)據(jù)就成了

somevalue = "";

這個(gè)數(shù)據(jù)類型不是nil 也不是 String。 解析成對(duì)象之后,如果直接向這個(gè)對(duì)象發(fā)送消息(eg:length,count 等等)就會(huì)直接崩潰。提示錯(cuò)誤為:

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

解決方法

其實(shí)一直沒(méi)有找到完美的解決辦法,坑了我很久。

1、最開(kāi)始的解決方法就是為了應(yīng)付當(dāng)前遇到的崩潰,看看哪個(gè)字段可能為空,那么就對(duì)該字段使用前進(jìn)行判斷,通過(guò)崩潰時(shí)的錯(cuò)誤提示可以看出,這樣的字段解析成的對(duì)象是 NSNull 類型的,所以可以直接判斷是不是此類型:

if (![isKindOfClass:[NSNull class]])
{
    // TODO
} 

因?yàn)樽侄螌?shí)在太多,就找一個(gè)補(bǔ)一個(gè)。

2、后來(lái)想徹底解決這問(wèn)題,就打算從數(shù)據(jù)源下手,其實(shí)應(yīng)該可以用正則表達(dá)式匹配這個(gè)null ,然后進(jìn)行替換,奈何正則是我的硬傷啊。于是就相出了一個(gè)山寨方法:字符串匹配。在獲取到服務(wù)器返回的Json時(shí),返回結(jié)果時(shí)string對(duì)象,于是就先替換 null 為 為空字符””,然后再解析。

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

這個(gè)方法本來(lái)很奏效,但是我這里的服務(wù)器返回極不簡(jiǎn)潔,各種垃圾數(shù)據(jù)(不吐槽這了)。。。反正這樣會(huì)導(dǎo)致json無(wú)法解析了。

3、最后沒(méi)有辦法,只能在解析的時(shí)候下手,把是NSNull 類型的值替換成nil。 一般就寫(xiě)個(gè)tool方法,然后解析時(shí)調(diào)用。但是嫌太麻煩,就想弄寫(xiě)個(gè)宏,通過(guò)搜索驚奇的發(fā)現(xiàn)宏也是可以有返回值的,結(jié)果如下:

#define VerifyValue(value)\
({id tmp;\
if ([value isKindOfClass:[NSNull class]])\
tmp = nil;\
else\
tmp = value;\
tmp;\
})\

宏里的最后一句語(yǔ)句便是返回值。然后在解析數(shù)據(jù)時(shí)調(diào)用宏:

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

4、參考
http://www.zlcode.com/2016/03/10/ios-json-null-solve/

5、如果你使用AFNetwork 這個(gè)庫(kù)做網(wǎng)絡(luò)請(qǐng)求的話,可以用以下代碼,自動(dòng)幫你去掉這個(gè)討厭的空值

self.removesKeysWithNullValues = YES;

6、終極方案
終于找到了一勞永逸的方案,牛逼的老外寫(xiě)了一個(gè)Category,叫做NullSafe ,在運(yùn)行時(shí)操作,把這個(gè)討厭的空值置為nil,而nil是安全的,可以向nil對(duì)象發(fā)送任何message而不會(huì)奔潰。這個(gè)category使用起來(lái)非常方便,只要加入到了工程中就可以了,你其他的什么都不用做,對(duì),就是這么簡(jiǎn)單。詳細(xì)的請(qǐng)去Github上查看;
https://github.com/nicklockwood/NullSafe

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,695評(píng)論 19 139
  • 在iOS開(kāi)發(fā)過(guò)程中經(jīng)常需要與服務(wù)器進(jìn)行數(shù)據(jù)通訊,Json就是一種常用的高效簡(jiǎn)潔的數(shù)據(jù)格式。問(wèn)題現(xiàn)象但是幾個(gè)項(xiàng)目下來(lái)...
    seventhboy閱讀 642評(píng)論 0 1
  • 在iOS開(kāi)發(fā)過(guò)程中經(jīng)常需要與服務(wù)器進(jìn)行數(shù)據(jù)通訊,Json就是一種常用的高效簡(jiǎn)潔的數(shù)據(jù)格式。 問(wèn)題現(xiàn)象 但是幾個(gè)項(xiàng)目...
    紅酒佳坊閱讀 1,473評(píng)論 1 3
  • 在iOS開(kāi)發(fā)過(guò)程中經(jīng)常需要與服務(wù)器進(jìn)行數(shù)據(jù)通訊,Json就是一種常用的高效簡(jiǎn)潔的數(shù)據(jù)格式。問(wèn)題現(xiàn)象但是幾個(gè)項(xiàng)目下來(lái)...
    莫許閱讀 638評(píng)論 0 0
  • 1. OKR:對(duì)可量化的指標(biāo),用kpi考核,對(duì)不能量化的創(chuàng)新性指標(biāo),用oki考核,企業(yè)、部門(mén)、個(gè)人的目標(biāo)要逐層分解...
    曲同寧閱讀 256評(píng)論 0 0

友情鏈接更多精彩內(nèi)容