iOS中nil、Nil、NULL和NSNull的理解和用法詳解
nil
這個也是條件編譯的,那麼對於我們Objective-C
開發來說,nil
就代表((void *)0)
。
我們使用nil
表示Objective-C
物件為空,如NSString *str = nil
。
我們給物件賦值時一般會使用object = nil,表示我想把這個物件釋放掉;
或者物件由於某種原因,經過多次release,於是物件引用計數器為0了,系統將這塊記憶體釋放掉,這個時候這個物件為nil,我稱它為“空物件”。(注意:我這裡強調的是“空物件”,下面我會拿它和“值為空的物件”作對比!!!)
所以對於這種空物件,所有關於retain的操作都會引起程式崩潰
如果1個類指標的值為nil 代表這個指標不指向任何物件.
Person *p1 = nil;
那麼這個時候 如果通過p1指標去訪問p1指標指向的物件的屬性 這個時候會執行報錯.
那麼這個時候,如果通過p1指標去呼叫物件的方法 執行不會報錯 但是方法不會執行 沒有任何反應
NSNull
NSNull
是繼承於NSObject
的型別。它是很特殊的類,它表示是空,什麼也不儲存,但是它卻是物件,只是一個佔位物件。
使用場景就不一樣了,比如說服務端介面中讓我們在值為空時,傳空。
1 2 3 4 |
NSDictionry *parameters = @{@"arg1" : @"value1", @"arg2" : arg2.isEmpty ? [NSNull null] : arg2};
|
這只是隨手舉的例子,當然我們也可以不傳這人蔘數。如果我們要統一,比如通過runtime
來動態將物件轉成我們的引數時,那麼可以統一將值為nil
的都設定為[NSNull null]
NSNull和nil的區別在於,nil是一個空物件,已經完全從記憶體中消失了,而如果我們想表達“我們需要有這樣一個容器,但這個容器裡什麼也沒有”的觀念時,我們就用到NSNull,我稱它為“值為空的物件”。如果你查閱開發文件你會發現NSNull這個類是繼承NSObject,並且只有一個“+ (NSNull *) null;”類方法。這就說明NSNull物件擁有一個有效的記憶體地址,所以在程式中對它的任何引用都是不會導致程式崩潰的
Nil
這個也是條件編譯的,那麼對於我們Objective-C
開發來說,Nil
也就代表((void *)0)
。
但是它是用於代表空類的。比如:
1 2 3 |
Class myClass = Nil; |
nil和Nil在使用上是沒有嚴格限定的,也就是說凡是使用nil的地方都可以用Nil來代替,反之亦然。只不過從程式設計人員的規約中我們約定俗成地將nil表示一個空物件,Nil表示一個空類
NULL
對於學習過C/C++
語言的朋友,對NULL
一定很熟悉吧?這就是在C/C++
中的空指標。
在C
語言中,NULL
是無型別的,只是一個巨集,它代表空。我們不研究C++
中的NULL
,因為在C++11
以後又有了新的定義,我們不深究。
這就是C
語言中所謂的NULL
(C++
的定義比較複雜,這裡不說了):
像C
語言中,我們定義了一個指標,當我們使用完以後,通常會設定指向NULL
。如果沒有設定,這個指標就成了所謂的野指標,然後其它地方不小心訪問了這個指標是很容易造成非法訪問的,常見的表現就是崩潰了。
既然Objective-C
是基於C
語言的面嚮物件語言,那麼也會使用到C
語言型別的指標,比如使用const char *
型別,判斷是否為空時,是使用p != NULL
來判斷的。
我們知道Object-C來源於C、支援於C,當然也有別於C。而NULL就是典型C語言的語法,它表示一個空指標
區別
NULL
、nil
、Nil
這三者對於Objective-C
中值是一樣的,都是(void *)0
,那麼為什麼要區分呢?又與NSNull
之間有什麼區別:
NULL
是巨集,是對於C
語言指標而使用的,表示空指標nil
是巨集,是對於Objective-C
中的物件而使用的,表示物件為空Nil
是巨集,是對於Objective-C
中的類而使用的,表示類指向空NSNull
是類型別,是用於表示空的佔位物件,與JS
或者服務端的null
類似的含意
雖然使用NULL的地方可以是nil 使用 nil的地方可以使用NULL 但是不建議大家去隨便使用.
C指標用NULL
int *p1 = NULL; p1指標不指向記憶體中的任何1塊空間.
OC的類指標用nil
Person *p1 = nil; p1指標不指向任何物件.