美文网首页
ios项目从NSArray/NSDictionary/NSSet

ios项目从NSArray/NSDictionary/NSSet

作者: Steven_Wu | 来源:发表于2017-01-26 17:06 被阅读264次
    >>Objective-C的集合对象,如NSArray、NSDictionary、NSSet等,是允许包含NSNull对象(即[NSNull null]),经常从服务器请求下来的json中包含null时,NSJSONSerialization解析时自动把null换成[NSNull null]。

    **
    例如:通过AFN从服务器请求下来的json数据显示为 { "list" : null },当AFN通过NSJSONSerialization解析成OC字典dic时,会自动把null换成[NSNull null]空对象(单例),即转化后dic = @{ @"list" : [NSNull null] },而我们在对空对象发送任何对象消息(-开头方法)时,都会报错。
    因为NSNull类只有一个+ (NSNull *)null;类方法,没有任何对象方法。报错通常为:-[NSNull count]: unrecognized selector sent to instance 0x10c684fb0之类
    **

    最近在项目中踩过一次大坑,如下是一段测试代码

    id list = dic[@"list"];
    
    if (list) {
        NSLog(@"list有值:%@",list);
    }
    
    if (list == nil) { //等价于 if(!list)
        NSLog(@"list == nil对象指针为nil");
    }
    
    if (list == [NSNull null]) { //[NSNull null]为单例,故所有NSNull类型的指针,全等于[NSNull null]
        NSLog(@"list就是单例[NSNull null]");
    }
    
    if ([list isKindOfClass:[NSNull class]]) {  /* list表面为id,实际为NSNull类型,
                                                 isKindOfClass是运行时方法,判断的是对象的真实类型*/
        NSLog(@"服务器返回的dic[list]=%@,其类型:%@",dic[@"list"],[dic[@"list"] class]);
    }
    
    if ([dic[@"list"] isKindOfClass:[NSNull class]]) {
        NSLog(@"服务器返回的dic[list]=%@,其类型:%@",dic[@"list"],[dic[@"list"] class]);
    }
    
    /*[aArr arrayWithArray:bArr]内部会将bArr遍历,类似for(int i = 0; i < bArr.count; i++){},
     此时bArr实际是[NSNull null]空对象(一个对象方法都没有),故会找不到count方法。*/
    NSMutableArray *listArrM = [NSMutableArray arrayWithArray: dic[@"list"]];
    
    

    打印结果如下:

    2017-01-19 16:01:14.411 [10440:154188] list有值:<null>
    //第二句条件显然不成立,list == [NSNull null]并不等于nil,故没有打印
    2017-01-19 16:01:14.411 [10440:154188] 服务器返回的dic[list]=<null>,其类型:NSNull
    2017-01-19 16:01:14.412 [10440:154188] list就是单例[NSNull null]
    2017-01-19 16:01:14.412 [10440:154188] 服务器返回的dic[list]=<null>,其类型:NSNull
    2017-01-19 16:01:14.447 [10440:154188] -[NSNull count]: unrecognized selector sent to instance 0x10c684fb0
    
    

    关于NSNull导致的报错解决起来也比较简单,可通过isKindOfClass:[NSNull class]来判断,进行单次错误拦截。也可以通过给NSNull增加分类的方式,将整个项目中,即将发生[NSNull null]无此方法的报错全部拦截,将空对象替换为nil即可。谷歌一下,会有很多答案。

    相关文章

      网友评论

          本文标题:ios项目从NSArray/NSDictionary/NSSet

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