在后臺(tái)返回值為Null為空時(shí),我們代碼沒(méi)有判斷時(shí)谍咆,程序就會(huì)崩潰禾锤。當(dāng)時(shí)一直很疑惑是為啥,后來(lái)發(fā)現(xiàn)是數(shù)據(jù)問(wèn)題摹察,由于服務(wù)器的數(shù)據(jù)庫(kù)中有些字段為空恩掷,然后以Json形式返回給客戶端時(shí)就會(huì)出現(xiàn)這樣的數(shù)據(jù)。當(dāng)我們通過(guò)一些第三方數(shù)據(jù)解析庫(kù)解析數(shù)據(jù)后供嚎,就會(huì)是下圖這種數(shù)據(jù)格式黄娘。null既不是字符串也不是nil所以我們有些判斷是沒(méi)用的。
解析成對(duì)象之后查坪,如果直接向這個(gè)對(duì)象發(fā)送消息(length,count 等等)就會(huì)直接崩潰。提示錯(cuò)誤為
-[NSNull length]: unrecognized selector sent to instance 0x388a4a70
解決辦法
1.對(duì)取值對(duì)象類型判斷宁炫。缺點(diǎn)是太過(guò)繁瑣偿曙,每次都要寫(xiě)。
#define kDictIsEmpty(dic) ([dic isKindOfClass:[NSNull class]])//宏
if (![@"你要取的值" isKindOfClass:[NSNull class]]){
//數(shù)據(jù)
}
2.字符串匹配羔巢。在獲取到服務(wù)器返回的Json時(shí)(返回結(jié)果是string對(duì)象)通過(guò)stringByReplacingOccurrencesOfString方法望忆,替換"null"為"空字符",然后解析竿秆。不過(guò)通過(guò)這個(gè)方法也有可能導(dǎo)致數(shù)據(jù)無(wú)法解析
json = [jsonStr stringByReplacingOccurrencesOfString:@":null" withString:@""];
3.解析時(shí)把null 類型替換成nil启摄。
//有返回值的宏
#define isToNull(value) \
({\
id tmp;\
if (![value isKindOfClass:[NSNull class]])\
tmp = value;\
else
tmp = nil;\
(tmp);\
})\
//調(diào)用方法
label.text = isToNull(dic[@"data"]);
4.如果使用是AFNetwork做網(wǎng)絡(luò)請(qǐng)求的話,可以用以下代碼幽钢,會(huì)自動(dòng)去除空值
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
AFJSONResponseSerializer *response = [AFJSONResponseSerializer serializer];
response.removesKeysWithNullValues = YES;//去除空值
manager.responseSerializer = response;//申明返回的結(jié)果是json類
去除前
去除后 所有為空的鍵值對(duì)都會(huì)被自動(dòng)去除
5.最有效而且簡(jiǎn)單的方法歉备。使用國(guó)外一位大牛寫(xiě)的Category,叫做NullSafe 匪燕,在運(yùn)行時(shí)操作蕾羊,把空值置為nil,而nil是安全的帽驯,可以向nil對(duì)象發(fā)送任何message而不會(huì)奔潰龟再。
具體使用方法項(xiàng)目有說(shuō)明