繁体   English   中英

什么最能说明nil? 那到底是什么

[英]What describes nil best? What's that really?

目前,我将其理解为一种“空对象”。 但是到底是什么呢?

Objective-C对象

首先,当您调用此命令时:

id someObject = [NSArray array];

someObject不是直接的数组对象,而只是指向它的指针。 这意味着,如果someObject等于0x1234 ,则内存中的该地址处有一个对象。

这就是为什么

id someOtherObject = someObject;

不复制对象。 现在两个指针都指向同一个对象。

指向0x0的指针

那么, nil是如何定义的呢? 让我们看一下源代码:

objc.h

#define nil __DARWIN_NULL    /* id of Nil instance */

_types.h

#ifdef __cplusplus
…
#else /* ! __cplusplus */
#define __DARWIN_NULL ((void *)0)
#endif /* __cplusplus */

看起来nil是指向地址0x0的指针。

所以呢?

让我们看一下《 Objective-C编程参考》所说的话:

发送消息到无

在Objective-C中,将消息发送到nil是有效的-它在运行时根本不起作用。 可可中有几种模式可以利用这一事实。 从消息返回nil的值也可能有效:…

返回的值是nil ,0或所有变量都初始化为0的struct 。它是哪个取决于预期的返回类型。 在Objective-C运行时中有一个明确的检查,看是否有消息发送给nil ,这意味着它确实非常快。

NilnilNULL

这些是3种类型。 这是所有定义:

#define Nil __DARWIN_NULL   /* id of Nil class */
#define nil __DARWIN_NULL   /* id of Nil instance */
#define NULL __DARWIN_NULL
#define __DARWIN_NULL ((void *)0)

可以看出,它们完全相同。 Nilnil由Objective-C定义, NULL来自C。

那有什么区别呢? 这只是关于风格。 它使代码更具可读性。

  • Nil用作不存在的类: Class someClass = Nil
  • nil用作不存在的实例: id someInstance = nil
  • NULL是指向不存在的内存部分的指针: char *theString = NULL

nil不是一个空对象,而是一个不存在的对象。 方法-getSomeObject如果不存在则不会返回空对象,而是返回nil ,告诉用户没有对象。

也许这很有意义:(两者都可以编译并运行。)

if (anObject == nil) {   // One cannot compare nothing to nothing,
                         // that wouldn't make sense.

if (anObject) {          // Correct, one checks for the existence of anObject

它不是一个空对象,根本就没有任何对象。 其余答案涵盖了其他语义,因此我将其保留为:)

nil仅应与指针一起使用,并且nil表示不指向任何内容的指针(其值为零)

NSString *myString = nil; // myString points to nothing
int x = nil; // invalid, "x" is not a pointer, but it will compile

没什么”。 但是,“无”可以像在尝试对NULL调用方法时一样发送消息而不会被杀死。

您可以查看问题以获取有关NULLnil更多信息。

这是一个空指针 -指向“无”的指针。

正式定义为Joshual定义-完全不指向任何对象的指针。

从实际的实现角度来看,尤其是在处理数据结构和算法时,nill通常会代表数据结构中的前哨或代表“无”的对象,例如在红黑树中,从技术上讲,所有叶节点是“零”,但它们仍然具有与叶节点相同或相似的属性和操作(颜色,指向父节点的指针等)-在这些情况下,它实际上是“没有对象” ...如果这有任何意义。

因此,从形式上讲,它是无物的指针,在实践中,它通常被视为无物的表示,但是它永远不会... null。

思考nil一种有用方法是想象它是“什么都不做”的空对象。

我的意思是“什么都不做”,您发送的任何消息都不会产生副作用。

从某种意义上说,它是“空的”,当您要求它提供任何属性的值时,它总是返回nil 因此它没有任何值->它是空的。
(实际上,这要复杂得多,当您要求返回一个非obj-c对象类型的属性的值时,您将获得指针大小为0的指针。因此,对于没有大于sizeof(void*)你得到0 ,但如果你问一个structdouble 32位系统上,你会得到一个不确定的结果 。我已经写了这个在这里 。)

也许我只是缺少明显的东西,但这似乎是一个语义问题。 与之类似,您可以使用许多不同的词来描述它,但是您的描述已经足够好了。

http://en.wikipedia.org/wiki/Null_(computer_programming)

需要澄清的是,在Objective-C中,nil和null不是同一回事。 它们在Objective-C中的表示方式与在数学或其他编程语言中的表示方式都不相同。

Nil实际上是0x0的特殊内存地址(至少编译器将其视为地址。)Nil用作已命名但未分配的对象的地址。 这样可以测试命名对象的存在/分配,并提供一种将消息发送到可能不存在的对象的安全方法。 在数学和某些语言中,您可以将标量变量比较为nil,而在Objective-c中则不应。 您应该只比较对象的地址。

相反,NULL意味着标准C定义为NULL==0的整数值,或者可以表示具有内存中特定地址的NSNull类的实际分配对象。 NSNull是一个单例对象,即每个应用程序仅存在一个。 它通常用作集合中其他对象的占位符。 您不能将其与任何其他对象进行比较。 您只能检查特定的指针是否指向单例NSNull对象。 但是请注意,作为分配的对象[NSNull null]!=NULL

由于分配地址NULL会将其分配给0x0的nil地址,因此出现了nil和NULL之间的混淆。 这样的代码可以工作,但有时会引起细微的问题。 最好养成不要混淆两者的习惯。

因此,在Objective-C中,nil,NUll和NSNull是三个容易混淆的不同但重叠的概念。 应该将Nil用于地址,将NULL用于标量值,将NSNull用作已分配对象的占位符。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM