[英]What describes nil best? What's that really?
目前,我將其理解為一種“空對象”。 但是到底是什么呢?
首先,當您調用此命令時:
id someObject = [NSArray array];
someObject
不是直接的數組對象,而只是指向它的指針。 這意味着,如果someObject
等於0x1234
,則內存中的該地址處有一個對象。
這就是為什么
id someOtherObject = someObject;
不復制對象。 現在兩個指針都指向同一個對象。
那么, 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
,這意味着它確實非常快。
Nil
, nil
, NULL
這些是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)
可以看出,它們完全相同。 Nil
和nil
由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
調用方法時一樣發送消息而不會被殺死。
您可以查看此問題以獲取有關NULL
與nil
更多信息。
這是一個空指針 -指向“無”的指針。
正式定義為Joshual定義-完全不指向任何對象的指針。
從實際的實現角度來看,尤其是在處理數據結構和算法時,nill通常會代表數據結構中的前哨或代表“無”的對象,例如在紅黑樹中,從技術上講,所有葉節點是“零”,但它們仍然具有與葉節點相同或相似的屬性和操作(顏色,指向父節點的指針等)-在這些情況下,它實際上是“沒有對象” ...如果這有任何意義。
因此,從形式上講,它是無物的指針,在實踐中,它通常被視為無物的表示,但是它永遠不會... null。
思考nil
一種有用方法是想象它是“什么都不做”的空對象。
我的意思是“什么都不做”,您發送的任何消息都不會產生副作用。
從某種意義上說,它是“空的”,當您要求它提供任何屬性的值時,它總是返回nil
。 因此它沒有任何值->它是空的。
(實際上,這要復雜得多,當您要求返回一個非obj-c對象類型的屬性的值時,您將獲得指針大小為0
的指針。因此,對於沒有大於sizeof(void*)
你得到0
,但如果你問一個struct
或double
32位系統上,你會得到一個不確定的結果 。我已經寫了這個在這里 。)
也許我只是缺少明顯的東西,但這似乎是一個語義問題。 與之類似,您可以使用許多不同的詞來描述它,但是您的描述已經足夠好了。
需要澄清的是,在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.