nil / Nil /NULL / NSNull区别

作者: lyking | 来源:发表于2016-06-24 11:07 被阅读151次
    标识 含义
    Null (void*)0 C指针的字面零值
    nil (id)0 ObjC对象的字面零值
    Nil (Class)0 ObjC类的字面零值
    NSNull [NSNull null] 用来表示零值的单独对象

    NOTICE: 苹果的编译器在编译时会生成objc_msgSend这样的方法来发送消息,当对象设置为nil时,它就不会去寻找是哪个类实例的消息,因此什么也不干,这是苹果的处理方式。

    若obj为nil:[obj message]将返回NO,而不是NSException
    若obj为NSNull:[obj message]将抛出异常NSException
    
    nil、Nil、NULL的使用对比

    先看下面做的一个实验:

    NSArray * array = [NSArray arrayWithObjects:@"good", @"morning", nil];
    // array = nil; // 输出:0
    // array = NULL; // 输出:0
    // array = Nil; // 输出:0 
    
    NSLog(@"%ld", array.count);// 分别使用上面三句注释的语句,输出值无区别
    
    
     Class class = [NSURL class];
    // class = Nil; // 输出:(null)
    // class = nil; // 输出:(null)
    // class = NULL; // 输出:(null) 
    
    NSLog(@"%@", class); // 分别使用上面三句注释的语句,输出值无区别 
    
    
    int a = 10; int * p = &a;
    // p = NULL; // 输出:0x0
    // p = nil; // 输出:0x0// 
    p = Nil; // 输出:0x0 
    
    NSLog(@"%p", p); // 分别使用上面三句注释的语句,输出值无区别
    

    结论:

    • nil、Nil、NULL在使用上是没有什么区别的,但是程序员的一个约定:C结构的指针使用NULL;对象指针使用nil;类对象指针使用Nil。
    • 另外NSNull和nil、Nil、NULL具有本质上的区别。NSNull是一个对象,而nil、Nil、NULL只是给指针赋空值。
    • 在另外,给一个赋值为nil的对象发送消息,不会产生异常。当然给一个赋值为Nil、NULL的对象发送消息也不会产生异常,这个在例子中已经证实。故根据此条结论的总结为:nil、Nil、NULL目的都是给一个指针赋值为空,给空指针发送消息不会产生异常
    NSNull 到底是个什么东西?我从来没有调用过这个类,那么它又是哪产生的?
    • 通过 search 和排查,我最终定位了这个问题,这个 NSNull 是由 AFNetworking 的一个函数回调产生的:
    • 我在取 responseObject 的某个 value 时,得到了一个 NSNull 对象,而这个对象本应该是一个 NSString 的。
    • 通过与 PHP 服务器同学联调,我们最终发现了这个问题产生的原因。
    • 原来,服务器同学在获取某个字段的时候,不小心填错了参数,导致获取到的字段为空。他将这个空作为这个 Key 的 Value 填入了 JSON。
    • iOS APP 这边,AFNetworking 发现了这个空,它跟 Objective-C 中的 nil 有着显著的区别,因为 Objective-C 中的 NSDictionary 是不允许某一个 Key 对应的 Value 为 nil的。 这个空,最终被转化成了一个 NSNull 对象。

    nil、Nil、NULL、NSNull之间的区别

    nil的含义

    指向一个对象的指针为空,用于给对象指针赋值为空,防止野指针的产生;也称nil为空对象:表示一个已经被释放了的对象,和值为空的对象(NSNull)不同。NSNull是一个对象,只不过这个对象的值为空
    #ifndef nil
    # if __has_feature(cxx_nullptr)
    # define nil nullptr
    # else
    # define nil __DARWIN_NULL
    # endif
    #endif

    给对象指针赋值为空:

    NSString * name = nil;
    NSString * url = nil;
    id object = nil;
    
    Nil的含义

    指向一个类的指针为空,用于给类对象指针赋值为空
    #ifndef Nil
    # if __has_feature(cxx_nullptr)
    # define Nil nullptr
    # else
    # define Nil __DARWIN_NULL
    # endif
    #endif

    给类对象赋值为空:

    Class class = Nil;
    
    NULL的含义

    指向C类型的指针,用于给C类型的指针赋值为空
    #if defined(__need_NULL)
    #undef NULL
    #ifdef __cplusplus
    # if !defined(MINGW32) && !defined(_MSC_VER)
    # define NULL __null
    # else
    # define NULL 0
    # endif
    #else
    # define NULL ((void*)0)
    #endif

    给C类型指针赋值:

    int * a = NULL;
    char * ch = NULL;
    struct aStruct = NULL;
    
    NSNull的含义

    NSNull是一个类,其继承自NSObject,只拥有一个类方法。实例对象表示这是一个内容为空的对象。主要用于数组、字典。

    NSMutableArray * mArray = [NSMutableArray array];
    
    [mArray addObject:[NSNull null]];
    
    NSLog(@"%@", [mArray firstObject]); // 输出为:<null>
    
    
    NSMutableDictionary * dict = [NSMutableDictionary dictionary];
    
    [dict setObject:[NSNull null] forKey:@"null"];
    
    NSLog(@"%@", dict[@"null"]); // 输出为:<null>
    

    由此可见,可用NSNull的实例对象在数组、字典中占位,其所占有的位置为空。

    参考:http://www.jianshu.com/p/562ecd82228f

    相关文章

      网友评论

        本文标题:nil / Nil /NULL / NSNull区别

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