簡體   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