美文网首页
iOS开发json解析崩溃的解决方案

iOS开发json解析崩溃的解决方案

作者: 本本的开心牧场 | 来源:发表于2018-03-31 23:07 被阅读0次

    在iOS开发中我们从接口获取的数据大多是json类型的,但是json转对象后总会出现一些NSNull类型,NSNull是个坑,因为他很可能会使我们的程序崩溃

    我觉得对nil、Nil、NULL和[NSNull null]的区别不是很了解 可以去看下这篇文章https://www.jianshu.com/p/69a6685782f3

    首先给出解决方案

    1.https://github.com/nicklockwood/NullSafe

    github上点赞过1k NullSafe是NSNull上的一个简单类别,对于任何无法识别的消息返回nil而不是抛出异常

    或者

    2自定义NSDictionary类拓展(原理:当我们给一个NSNull对象发送消息的话,可能会崩溃(null是有内存的),而发送给nil的话,是不会崩溃的)

    -----有在网上看到其他博客是NSNull类型全部转换成@""空字符串的,但是我觉得nil更好些

    #import <Foundation/Foundation.h>
    
    @interface NSDictionary (AVHelper)
    - (id)av_safeValueForKey:(NSString *)key;
    - (NSDictionary *)av_safeValueArrayForKey:(NSString *)key;
    - (NSDictionary *)av_safeValueMutableArrayForKey:(NSString *)key;
    - (NSDictionary *)av_safeValueDictonaryForKey:(NSString *)key;
    - (NSDictionary *)av_safeValueMutableDictionaryForKey:(NSString *)key;
    - (NSDictionary *)av_safeValueDateForKey:(NSString *)key;
    @end
    
    #import "NSDictionary+AVHelper.h"
    
    @implementation NSDictionary (AVHelper)
    
    #pragma mark - public method
    
    - (id)av_safeValueForKey:(NSString *)key {
        id value = [self valueForKey:key];
        if([value isKindOfClass:[NSNull class]]){
            value = nil;
        }
        return value;
    }
    
    - (NSDictionary *)av_safeValueArrayForKey:(NSString *)key {
        return [self av_safeValueForKey:key originalClass:[NSArray class]];
    }
    
    - (NSDictionary *)av_safeValueMutableArrayForKey:(NSString *)key {
        return [self av_safeValueForKey:key originalClass:[NSMutableArray class]];
    }
    
    - (NSDictionary *)av_safeValueDictonaryForKey:(NSString *)key {
        return [self av_safeValueForKey:key originalClass:[NSDictionary class]];
    }
    
    - (NSDictionary *)av_safeValueMutableDictionaryForKey:(NSString *)key {
        return [self av_safeValueForKey:key originalClass:[NSMutableDictionary class]];
    }
    
    - (NSDictionary *)av_safeValueDateForKey:(NSString *)key {
        return [self av_safeValueForKey:key originalClass:[NSDate class]];
    }
    
    #pragma mark - private method
    - (id)av_safeValueForKey:(NSString *)key originalClass:(Class)aClass {
        id value = [self valueForKeyPath:key];
        if ([value isKindOfClass:[NSNull class]]) {
            value = nil;
        }
        
        if (value) {
            return value;
        }
        
        if (aClass == [NSString class]) {
            return @"";
        }
        
        if (aClass == [NSNumber class]) {
            return @0;
        }
        
        NSArray *array = @[@"NSArray",
                           @"NSMutaleArray",
                           @"NSDictionary",
                           @"NSMutableDictionary",
                           @"NSDate"];
        
        for (NSString *className in array) {
            Class bClass = NSClassFromString(className);
            if (aClass != bClass) {
                continue;
            }
            
            value = [[bClass alloc] init];
            break;
        }
        
        return value;
    }
    
    @end
    

    如果有兴趣继续看

    写了个小demo,问题产生原因一目了然

    #import <Foundation/Foundation.h>
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            NSNull *pit = [NSNull null];
            NSDictionary *dic=  @{
                                  @"debug":pit
                                  };
            id value = dic[@"debug"];
            /*
             注销这行代码程序会崩溃
            */
    //        if ([value isKindOfClass:[NSNull class]]) {
    //            value = nil;
    //        }
            
            NSString *str = value;
            if (str.length==0) {
                NSLog(@"发消息时不崩溃");
            }
            
            NSLog(@"%@",str);
        }
        return 0;
    }
    
    没有注销代码时
    注销代码时

    相关文章

      网友评论

          本文标题:iOS开发json解析崩溃的解决方案

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