【问题标题】:Are NULL and nil equivalent?NULL 和 nil 是等价的吗?
【发布时间】:2010-03-17 10:56:26
【问题描述】:

其实我的问题是:nullnil 是否等效?

我有一个例子,但是当它们不相等时我很困惑。

NSNull *nullValue = [NSNull null];
NSArray *arrayWithNull = [NSArray arrayWithObject:nullValue];
NSLog(@"arrayWithNull: %@", arrayWithNull);
id aValue = [arrayWithNull objectAtIndex:0];

if (aValue == nil) {
    NSLog(@"equals nil");
} else if (aValue == [NSNull null]) {
    NSLog(@"equals NSNull instance");
    if ([aValue isEqual:nil]) {
        NSLog(@"isEqual:nil");
    }
}

在上面的例子中,它显示nullnil 不相等,它显示“等于 NSNull 实例”

NSString *str=NULL;
id str1=nil;
if(str1 == str)
{
   printf("\n IS EQUAL........");

}
else
{
    printf("\n NOT EQUAL........");
}

在第二种情况下,它显示两者相等并显示“IS EQUAL”。

任何人的帮助将不胜感激。

谢谢你, 莫尼什。

【问题讨论】:

标签: objective-c null nsnull


【解决方案1】:

nilNULL本质上是一样的,nil类似于(NSObject *)0,而NULL更像(void *)0。但两者都是整数值为零的指针。您可以向nil 发送消息而不会引发错误。

NSNullNULL(当然是nil)是不同的东西。您只需使用NSNull 作为助手将empty 对象添加到NSArray 或另一个容器类,因为您不能将nil 添加到它们。因此,您使用[NSNull null] 作为替代,并且您必须检查数组元素是否为NSNull,而不是nil(它永远不会等于nil)。

【讨论】:

  • 显然根据 Apple Docs NSNull is Not (NSObject *)0 but is a valid instance.
  • 这是否意味着 (str1==str) 对 == 使用运算符重载,这是一个值比较而不是身份比较?这可能是导致原始问题的混淆来源。
  • 确实,NSNull 是一个有效的对象。这就是我想说的。顺便说一句,Objective C 中没有运算符重载。 Objective C 对象的比较只是指针比较。
  • @Warren P:FWIW,您可以使用 == 与 [NSNull null] 进行比较,只是因为它保证始终返回相同的对象实例。
【解决方案2】:

来自http://www.iphonedevsdk.com/forum/iphone-sdk-development/34826-nil-vs-null.html

nilNULL 可以 100% 互换。

发件人:

  • NULL 用于 C 风格的内存指针。
  • nil 用于 Objective-C 对象。
  • Nil 用于 Objective-C 类。

每当您编写 Objective-C 代码时,请使用 nil 每当您编写 C 代码时,请使用 NULL

但最终它们都被定义为相同的东西——我认为是 (void *)0——所以在实践中这并不重要。

【讨论】:

  • NSNull 与 NULL 不同。
  • 你是对的。 [NSNull null] 是一个单例值,用于在禁止使用 nil 的情况下表示 nil 值——例如在集合类中(如 NSDictionary、NSArray、NSSet 或可变变体)。
  • 换句话说,它被用作集合中的占位符,不允许您将项目设置为 nil。
  • 我可以在 Objective-C 实现文件的 C 代码中使用 nil。既然你可以组合它们,我可以组合 nil 和 NULL 吗?只是要确定。 :-)
【解决方案3】:

概念是一样的,不同的是向nil发送消息(调用方法)是有效的。

NSNull 是一个真正的(单例)类,可用于不接受 NULL 或 nil 值的数组或字典。

【讨论】:

    【解决方案4】:

    它们之间最大的区别:向NSNULL 对象发送消息可能会导致崩溃,而向nil 发送任何消息都很酷。例如,如果您使用键路径来获取数组,如下所示:

    NSArray *departmentNames = [departments valueForKey:@"name"];
    

    那么对于namenil 的任何部门,您将拥有一个NSNULL 对象。所以,这会导致崩溃:

    for (NSString *name in departmentNames)
        NSLog(@"%@", [name lowercaseString]);
    

    只要 nameNSNull,因为您刚刚将未知选择器 (lowercaseString) 发送到 NSNull

    课程:在向其元素发送任何消息之前检查数组中的NSNull 对象。

    for (NSString *name in departmentNames)
        if (name != [NSNull null])
             NSLog(@"%@", [name lowercaseString]);
    

    【讨论】:

      【解决方案5】:

      不,NSNullnil 不一样。它们都代表缺乏价值,您可能希望对它们一视同仁,但它们仍然不平等。

      NSNull 对象实例表示空值,例如当您从具有空值的数据库中读取数据时。

      nil 值是一个空指针,即它不指向任何对象实例。

      在您的第二个代码中,您没有任何 NSNull 实例。包含空指针的 NSString 指针不是 NSNull 实例,它仍然只是空指针。您将一个空指针与另一个空指针进行比较,它们当然是相等的。

      【讨论】:

        【解决方案6】:

        确保将 [NSNull null] 类型转换为要比较的对象类型

        NSArray list;
        if(list==(NSArray *)[NSNull null])
            // do something
        

        否则您将收到一条警告消息,提示“不同指针类型的比较('type *' 和 'NSNull *')

        【讨论】:

          猜你喜欢
          • 2018-01-25
          • 1970-01-01
          • 2012-11-22
          • 1970-01-01
          • 2010-12-25
          • 1970-01-01
          • 2016-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多