1. 程式人生 > >後臺傳回null的崩潰容錯處理

後臺傳回null的崩潰容錯處理

kvc rem cin 字符 == model 小數精度 mod val

後臺使用orc 數據庫...對於沒有賦值的字段,會返回<null>

直接使用蘋果自帶的kvc 去將數據轉模型,,會crash [model setValuesForKeysWithDictionary:dataDic];

雖然後臺也會盡量避免傳回<null> ,但是作為程序員應該嚴謹對待每一個可能崩潰的問題.

有 解決方案 就是在每一個 可能傳回null 的地方 使用 if([m_result isEqual:[NSNUll null]]) 去判斷,但這不是一個有追求的程序員會滿足的方式..

網上傳說老外寫了一個Category,叫做NullSafe..只支持到ios9,3 ,實測 並沒有解決我的問題..

還有通過在AFN 裏面 AFJSONResponseSerializer的 serializerWithReadingOptions:方法中添加

serializer.removesKeysWithNullValues = YES; 實測 也並沒有解決此問題

最後在stack overflow 上找到解決方案.將其寫的兩個方法 放入數組和字典的category裏面. 完美解決..在每次請求回來數據,,統一處理..

廢話不多說,上代碼

@implementation NSDictionary (null)

- (NSDictionary *)dictionaryByReplacingNullsWithBlanks {

const NSMutableDictionary *replaced = [self mutableCopy];

const id nul = [NSNull null];

const NSString *blank = @"";

for (NSString *key in self) {

id object = [self objectForKey:key];

if (object == nul) [replaced setObject:blank forKey:key];

else if ([object isKindOfClass:[NSDictionary class]]) [replaced setObject:[object dictionaryByReplacingNullsWithBlanks] forKey:key];

else if ([object isKindOfClass:[NSArray class]]) [replaced setObject:[object arrayByReplacingNullsWithBlanks] forKey:key];

}

return [NSDictionary dictionaryWithDictionary:[replaced copy]];

}

@implementation NSArray (null)

- (NSArray *)arrayByReplacingNullsWithBlanks {

NSMutableArray *replaced = [self mutableCopy];

const id nul = [NSNull null];

const NSString *blank = @"";

for (int idx = 0; idx < [replaced count]; idx++) {

id object = [replaced objectAtIndex:idx];

if (object == nul) [replaced replaceObjectAtIndex:idx withObject:blank];

else if ([object isKindOfClass:[NSDictionary class]]) [replaced replaceObjectAtIndex:idx withObject:[object dictionaryByReplacingNullsWithBlanks]];

else if ([object isKindOfClass:[NSArray class]]) [replaced replaceObjectAtIndex:idx withObject:[object arrayByReplacingNullsWithBlanks]];

}

return [replaced copy];

}

use method simple

在封裝的網絡請求獲取到後臺數據的地方 將數據處理一下

NSData *data = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error]; NSLog(@"error :%@", error);

//生成字典 NSDictionary *responseDic = (NSDictionary *)data;

//處理後臺返回數據裏面有的情況

NSDictionary *dic = [responseDic dictionaryByReplacingNullsWithBlanks];

NSDictionary *respondsData = dic[@"data"];

NSDictionary *status = dic[@"status"];

NSInteger code = [[status objectForKey:@"code"] intValue];

NSLog(@"codeStr----%ld...%@",(long)code,respondsData);

if (code == 200){

if (successBlock) {

successBlock(dic);

}

} else

{

NSDictionary *status = dic[@"status"];

NSString *alertResult = [status objectForKey:@"message"];

//防止為空的提示

if(alertResult.length >1){

[XDProgressHUD showToastWithTitle:[NSString stringWithFormat:@"%@", alertResult]];

}

}

在踩過後臺傳回nsnull 這個坑之後,項目中很多涉及到金額 的字段 有的後臺返回的是字符串,有的是返回的double 類型,float類型..問題來了..字符串的金額是沒有問題的.但是如果是double flaot 類型 ,,金額數字在經過 [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error]; 這個 ios 自帶的json 解析之後 會遭遇 ( 6.66 變成 6.59999999999999),此問題 安卓不會有 ,所以非常惡心,,需要自己再去處理 或者跟後臺商量改成字符串類型,,(強烈建議 如果後臺返回的數據 是float double 盡量使用字符串 不要使用 float double 避免出現精度丟失),,遭遇此問題 我的解決方案 是基於上面處理nsnull 問題的方案 ,,上代碼

- (NSDictionary *)dictionaryByReplacingNullsWithBlanks {

const NSMutableDictionary *replaced = [self mutableCopy];

const id nul = [NSNull null];

const NSString *blank = @"";

for (NSString *key in self) {

id object = [self objectForKey:key];

if (object == nul) [replaced setObject:blank forKey:key];

else if ([object isKindOfClass:[NSDictionary class]]) [replaced setObject:[object dictionaryByReplacingNullsWithBlanks] forKey:key];

else if ([object isKindOfClass:[NSArray class]]) [replaced setObject:[object arrayByReplacingNullsWithBlanks] forKey:key];

if([object isKindOfClass:[NSNumber class]]){

// 如果後臺返回有 double float類型,,此步驟時候 經過ios 自帶json解析(6.66 就已經變成了6.5999999999) 下面的方法 全局處理 保留三位小數精度,,相當於還原了 ios自帶json 解析丟失精度的問題,親測有效)

double conversionValue = (double)[object floatValue];

NSString *d2Str = [NSString stringWithFormat:@"%.3lf",conversionValue];

NSDecimalNumber *num1 = [NSDecimalNumber decimalNumberWithString:d2Str];

NSString *strD2 = [num1 stringValue];

[replaced setObject:strD2 forKey:key];

}

}

return [NSDictionary dictionaryWithDictionary:[replaced copy]];

}

轉自:http://www.jianshu.com/p/e8e113a94e1d

後臺傳回null的崩潰容錯處理