iOS解决返回字段为空导致程序闪退的问题

做过iOS开发的,在开始的时候一定会遇到这样的问题,明明代码写的好好的,但是有时候莫名其妙的程序就崩溃了,然后下全局断点发现,很多时候是因为服务器返回的字段为null,导致空指针,从而导致程序崩溃。这时,会想各种方法解决。接下来给各位介绍三种我使用的方法。

最近发现一个比较好的解决方法:

第一种方法

前提是你用的是AFNetworking第三方。
设置下面属性:
serializer.removesKeysWithNullValues = YES;
在哪里设置呢?搜索AFURLResponseSerialization.m类,在定位到AFJSONResponseSerializer类,如下图:

iOS解决返回字段为空导致程序闪退的问题_第1张图片
20171017115858716.png

然后定位:AFJSONObjectByRemovingKeysWithNullValues

static id AFJSONObjectByRemovingKeysWithNullValues(id JSONObject,NSJSONReadingOptions readingOptions) {
    if ([JSONObject isKindOfClass:[NSArray class]]) {
        NSMutableArray *mutableArray = [NSMutableArray arrayWithCapacity:[(NSArray *)JSONObject count]];
        for (id value in (NSArray *)JSONObject) {
            [mutableArray addObject:AFJSONObjectByRemovingKeysWithNullValues(value, readingOptions)];
        }

        return (readingOptions & NSJSONReadingMutableContainers) ? mutableArray : [NSArray arrayWithArray:mutableArray];
    } else if ([JSONObject isKindOfClass:[NSDictionary class]]) {
        NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithDictionary:JSONObject];
        for (id  key in [(NSDictionary *)JSONObject allKeys]) {
            id value = (NSDictionary *)JSONObject[key];
            if (!value || [value isEqual:[NSNull null]]) {
                //这里是本库作者的源代码
                //[mutableDictionary removeObjectForKey:key];
                //下面是改动后的,将空指针类型改为空字符串
                mutableDictionary[key] = @"";
            } else if ([value isKindOfClass:[NSArray class]] || [value isKindOfClass:[NSDictionary class]]) {
                mutableDictionary[key] = AFJSONObjectByRemovingKeysWithNullValues(value, readingOptions);
            }
        }

        return (readingOptions & NSJSONReadingMutableContainers) ? mutableDictionary : [NSDictionary dictionaryWithDictionary:mutableDictionary];
    }

    return JSONObject;
}

修改部分就是将空指针value改为空字符串。

如果你没有用AFN也没有关系下面我们来看看这个终极解决的办法:

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

iOS解决返回字段为空导致程序闪退的问题_第2张图片
20171017130649975.png

但是第二种方法不知道是不是已经有AFNetworking的缘故,我自行倒入后发现没有效果,可能是和AFNetworking冲突的缘故吧。

第三种方法
自己写一个工具类NullClean,集成自NSObject,将所有的null变成@"",
代码如下:
NullClean.h中申明一个方法,以便于外界调用
+(id)changeType:(id)myObj;
接下来在NullClean.m中实现


#pragma mark - 公有方法
//类型识别:将所有的NSNull类型转化成@""
+(id)changeType:(id)myObj
{
    if ([myObj isKindOfClass:[NSDictionary class]])
    {
        return [self nullDic:myObj];
    }
    else if([myObj isKindOfClass:[NSArray class]])
    {
        return [self nullArr:myObj];
    }
    else if([myObj isKindOfClass:[NSString class]])
    {
        return [self stringToString:myObj];
    }
    else if([myObj isKindOfClass:[NSNull class]])
    {
        return [self nullToString];
    }
    else
    {
        return [NSString stringWithFormat:@"%@",myObj];//此处都转成了string类型,后期特殊需要可以改
    }
}

#pragma mark - 私有方法
//将NSDictionary中的Null类型的项目转化成@""
+(NSDictionary *)nullDic:(NSDictionary *)myDic
{
    NSArray *keyArr = [myDic allKeys];
    NSMutableDictionary *resDic = [[NSMutableDictionary alloc]init];
    for (int i = 0; i < keyArr.count; i ++)
    {
        id obj = [myDic objectForKey:keyArr[i]];
        
        obj = [self changeType:obj];
        
        [resDic setObject:obj forKey:keyArr[i]];
    }
    return resDic;
}

//将NSDictionary中的Null类型的项目转化成@""
+(NSArray *)nullArr:(NSArray *)myArr
{
    NSMutableArray *resArr = [[NSMutableArray alloc] init];
    for (int i = 0; i < myArr.count; i ++)
    {
        id obj = myArr[i];
        
        obj = [self changeType:obj];
        
        [resArr addObject:obj];
    }
    return resArr;
}

//将NSString类型的原路返回
+(NSString *)stringToString:(NSString *)string
{
    return string;
}

//将Null类型的项目转化成@""
+(NSString *)nullToString
{
    return @"";
}


在请求到数据之后直接将请求到的数据作为入参,返回结果就是清完null之后的数据了

你可能感兴趣的:(iOS解决返回字段为空导致程序闪退的问题)