美文网首页iOS技术
iOS解决返回字段为空导致程序闪退的问题

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

作者: Leeson1989 | 来源:发表于2018-08-10 14:48 被阅读255次

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

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

    第一种方法

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

    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 <NSCopying> 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

    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解决返回字段为空导致程序闪退的问题

        本文链接:https://www.haomeiwen.com/subject/dvgkbftx.html