iOS中json解析出現(xiàn)的null,nil,NSNumber的解決辦法
在iOS開發(fā)過程中經(jīng)常需要與服務(wù)器進行數(shù)據(jù)通訊,Json就是一種常用的高效簡潔的數(shù)據(jù)格式。
JSON建構(gòu)有兩種結(jié)構(gòu):
json簡單說就是javascript中的對象和數(shù)組,所以這兩種結(jié)構(gòu)就是對象和數(shù)組2種結(jié)構(gòu),通過這兩種結(jié)構(gòu)可以表示各種復(fù)雜的結(jié)構(gòu)
1、對象:對象在js中表示為“{}”擴起來的內(nèi)容,數(shù)據(jù)結(jié)構(gòu)為 {key:value,key:value,...}的鍵值對的結(jié)構(gòu),在面向?qū)ο蟮恼Z言中,key為對象的屬性,value為對應(yīng)的屬性值,所以很容易理解,取值方法為對象.key 獲取屬性值,這個屬性值的類型可以是 數(shù)字、字符串、數(shù)組、對象幾種。
2、數(shù)組:數(shù)組在js中是中括號“[]”擴起來的內(nèi)容,數(shù)據(jù)結(jié)構(gòu)為 ["java","javascript","vb",...],取值方式和所有語言中一樣,使用索引獲取,字段值的類型可以是數(shù)字、字符串、數(shù)組、對象幾種。
經(jīng)過對象、數(shù)組2種結(jié)構(gòu)就可以組合成復(fù)雜的數(shù)據(jù)結(jié)構(gòu)了。
問題現(xiàn)象
但是幾個項目下來一直遇到一個坑爹的問題,程序在獲取某些數(shù)據(jù)之后莫名崩潰。其實很早就發(fā)現(xiàn)了原因:由于服務(wù)器的數(shù)據(jù)庫中有些字段為空,然后以Json形式返回給客戶端時就會出現(xiàn)這樣的數(shù)據(jù):
"somevalue":null
通過JsonKit 這個第三方庫解析出來的數(shù)據(jù)就成了
somevalue = "<null>";
這個數(shù)據(jù)類型不是nil 也不是 String。 解析成對象之后,如果直接向這個對象發(fā)送消息(eg:length,count 等等)就會直接崩潰。提示錯誤為:
-[NSNull length]: unrecognized selector sent to instance 0x388a4a70
解決方法
其實一直沒有找到完美的解決辦法,坑了我很久。
1、最開始的解決方法就是為了應(yīng)付當前遇到的崩潰,看看哪個字段可能為空,那么就對該字段使用前進行判斷,通過崩潰時的錯誤提示可以看出,這樣的字段解析成的對象是 NSNull 類型的,所以可以直接判斷是不是此類型:
if (![isKindOfClass:[NSNull class]]){xxxxxxx;}
因為字段實在太多,就找一個補一個。
2、后來想徹底解決這問題,就打算從數(shù)據(jù)源下手,其實應(yīng)該可以用正則表達式匹配這個null ,然后進行替換,奈何正則是我的硬傷啊。于是就相出了一個山寨方法:字符串匹配。在獲取到服務(wù)器返回的Json時,返回結(jié)果時string對象,于是就先替換 null 為 為空字符””,然后再解析。
json = [jsonStr stringByReplacingOccurrencesOfString:@":null" withString:@":\"\""];
這個方法本來很奏效,但是我這里的服務(wù)器返回極不簡潔,各種垃圾數(shù)據(jù)(不吐槽這了)。。。反正這樣會導(dǎo)致json無法解析了。
3、最后沒有辦法,只能在解析的時候下手,把是NSNull 類型的值替換成nil。 一般就寫個tool方法,然后解析時調(diào)用。但是嫌太麻煩,就想弄寫個宏,通過搜索驚奇的發(fā)現(xiàn)宏也是可以有返回值的,結(jié)果如下:
#define VerifyValue(value)\
({id tmp;\
if ([value isKindOfClass:[NSNull class]])\
tmp = nil;\
else\
tmp = value;\
tmp;\
})\
宏里的最后一句語句便是返回值。然后在解析數(shù)據(jù)時調(diào)用宏:
contact.contactPhone = VerifyValue(contactDic[@"send_ContactPhone"]);
4、如果你使用AFNetwork 這個庫做網(wǎng)絡(luò)請求的話,可以用以下代碼,自動幫你去掉這個討厭的空值
self.removesKeysWithNullValues = YES;
5、終極方案
終于找到了一勞永逸的方案,牛逼的老外寫了一個Category,叫做NullSafe ,在運行時操作,把這個討厭的空值置為nil,而nil是安全的,可以向nil對象發(fā)送任何message而不會奔潰。這個category使用起來非常方便,只要加入到了工程中就可以了,你其他的什么都不用做,對,就是這么簡單。詳細的請去Github上查看;
相關(guān)文章
iOS 鍵盤輸入限制(只能輸入字母,數(shù)字,禁止輸入特殊符號)
本文主要介紹了iOS中鍵盤輸入限制(只能輸入字母,數(shù)字,禁止輸入特殊符號)的方法。具有很好的參考價值。下面跟著小編一起來看下吧2017-04-04
iOS 開發(fā)之 - 關(guān)閉鍵盤 退出鍵盤 的5種方式
這篇文章主要介紹了iOS 開發(fā)之 - 關(guān)閉鍵盤 退出鍵盤 的5種方式的相關(guān)資料,需要的朋友可以參考下2016-09-09
iOS實現(xiàn)對不同分辨率設(shè)備的字號大小適配方法
下面小編就為大家分享一篇iOS實現(xiàn)對不同分辨率設(shè)備的字號大小適配方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-01-01
iOS App開發(fā)中UISearchBar搜索欄組件的基本用法整理
iOS開發(fā)組件中自帶的UISearchBar提供了很多基礎(chǔ)和好用的搜索欄UI功能,下面就來總結(jié)一下iOS App開發(fā)中UISearchBar搜索欄組件的基本用法整理,需要的朋友可以參考下2016-05-05

