ios 中nil NSNull null kCFNull的區(qū)別

轉(zhuǎn)載在 http://blog.csdn.net/xunyn/article/details/8283653
http://www.reibang.com/p/3aaefb3bcf73
1筝野、nil和null從字面意思來理解比較簡單胖翰,nil是一個(gè)對象还惠,而NULL是一個(gè)值戴而,我的理解為nil是將對象設(shè)置為空石景,而null是將基本類型設(shè)置為空的竖哩,個(gè)人感覺有點(diǎn)像屬性當(dāng)中该抒,基本類型分配為assign NSString類型一般分配copy懂算,而對象一般用retain窿祥。而且我們對于nil調(diào)用方法株憾,不會產(chǎn)生crash或者拋出異常。看一段nil -> Null-pointer to objective- c object

NIL -> Null-pointer to objective- c class

null-> null pointer to primitive type or absence of data.

看一下用法

NSURL *url = nil嗤瞎;

Class class = Nil墙歪;

int *pointerInt = NULL;

nil是一個(gè)對象指針為空贝奇,Nil是一個(gè)類指針為空虹菲,NULL是基本數(shù)據(jù)類型為空。這些可以理解為nil掉瞳,Nil毕源, NULL的區(qū)別吧。

2陕习、NSNULL霎褐,NULL和nil在本質(zhì)上應(yīng)該是一樣的,NULL和nil其實(shí)就是0该镣,但是在Objective-c中冻璃,對于像NSArray這樣的類型,nil或NULL不能做為加到其中的Object损合,如果定義了一個(gè)NSArray省艳,為其分配了內(nèi)存,又想設(shè)置其中的內(nèi)容為空塌忽,則可以用[NSNULL null返回的對對象來初始化NSArray中的內(nèi)容拍埠,我的感覺有點(diǎn)像C語言中malloc一個(gè)內(nèi)存空間,然后用memset初始化這段空間里的值為0土居。

_viewControllers = [[NSMutableArray alloc] init];  
for (unsigned i = 0; i < _pages; i++) {  
[_viewControllers addObject:[NSNull null]];  
}  
ymBaseController *controller = [_viewControllers objectAtIndex:page];  
         if ((NSNull *)controller == [NSNull null])   
    {  
...  
    }  
    [_viewControllers replaceObjectAtIndex:page withObject:controller];  

3枣购、一個(gè)可以研究一下的問題在dealloc中-(void) dealloc{self.test = nil; [_test release];test = nil;}這幾個(gè)的區(qū)別先說最簡單的 [_test release]; 這個(gè)就是將引用技術(shù)減1,所謂的引用計(jì)數(shù)就是看看有多個(gè)指針指向一塊內(nèi)存實(shí)體擦耀,當(dāng)release一次棉圈,就是指針減少一個(gè),release到了0的時(shí)候眷蜓,就是真正把這塊內(nèi)存歸還給系統(tǒng)的時(shí)候了再說self.test = nil;說明一下 屬性和setter和getter方法就不難理解了-(void) setTest:(NSString *)newString{if(_test != newString)[_test release];_test = [newString retain];}-(NSString *)test{return _test;}這個(gè)是setter和getter方法分瘾,而在這個(gè)問題中相當(dāng)于剛才的代碼改變?yōu)閕f(_test != nil)[_test release];_test = nil;現(xiàn)在就比較容易解釋了,setter方法會retain nil對象吁系,在這之前已經(jīng)先release了舊的對象德召,這個(gè)方法優(yōu)點(diǎn)是成員變量連指向隨機(jī)數(shù)據(jù)的機(jī)會都沒有,而通過別的方式汽纤,就可能會出現(xiàn)指向隨機(jī)數(shù)據(jù)的情況上岗。當(dāng)release了之后,萬一有別的方法要用要存取它蕴坪,如果它已經(jīng)dealloc了肴掷,可能就會crash敬锐,而指向nil之后,就不會發(fā)生錯(cuò)誤了呆瞻。nil說白了就是計(jì)數(shù)器為0台夺,這么說吧,當(dāng)真正release一個(gè)對象的時(shí)候痴脾,NSLog是打印不了它指向的內(nèi)存控件的颤介,而當(dāng)nil的時(shí)候,是可以打印出來指向的一個(gè)內(nèi)存空間明郭。那么現(xiàn)在也不難解釋test = nil; 單純的這種用法可以說是自己給自己制造內(nèi)存泄露买窟,這里可以這么理解,就是相當(dāng)于將指向?qū)ο蟮闹羔樦苯雍蛯ο笠坏秲蓴嗔耸矶āV苯幼宼est指向nil,而內(nèi)存實(shí)體不會消失瞳购,也不會有系統(tǒng)回收话侄。

先來看個(gè)stackOverflow上的例子:

if (nameTextField.text != (id)[NSNull null] || nameTextField.text.length != 0 ) {
    NSString *msg = [[NSString alloc] initWithFormat:@"Hello, %@", txtName.text]; 
    [lblMessage setText:msg];
}

結(jié)果:無論nameTextField.text 是否為空,都會進(jìn)入到if 條件句中学赛。
錯(cuò)誤在: nameTextField.text 如果為空年堆,那么它 ==nil 而不是 (id)(NSNull null),所以無論如何,nameTextFiled != (id)[NSNull null] 都是true

我們先來看下這些空值的定義:

nil: Defines the id of a null instance盏浇,指向一個(gè)(實(shí)例)對象的空指針
例如:
NSString *msg = nil;
NSDate *date =nil;
Nil: Defines the id of a null class变丧,指向一個(gè)類的空指針
例如:
Class class = Nil;
NULL:定義其他類型(基本類型、C類型)的空指針
char *p = NULL;
NSNull:數(shù)組中元素的占位符绢掰,數(shù)據(jù)中的元素不能為nil(可以為空痒蓬,也就是NSNull),
原因:nil 是數(shù)組的結(jié)束標(biāo)志
如果用nil滴劲,就會變成

NSArray *array = [NSArray arrayWithObjects:
[[NSObject alloc] init], 
nil,
[[NSObject alloc] init], 
[[NSObject alloc] init], 
nil];攻晒,

那么數(shù)組到第二個(gè)位置就會結(jié)束。打印[array count]的話會顯示1而不是5
kCFNull: NSNull的單例
CoreFoundation 中有一段對 kCFNull的定義班挖,實(shí)際上就是 NSNull 的單例

typedef const struct CF_BRIDGED_TYPE(NSNull) __CFNull * CFNullRef;

CF_EXPORT
CFTypeID CFNullGetTypeID(void);

CF_EXPORT
const CFNullRef kCFNull; // the singleton null instance

NSNull *null1 = (id)kCFNull;
NSNull *null2 = [NSNull null];
Talking is cheap ,show me the code!

NSLog(@"nil is %p",nil);
NSLog(@"Nil is %p",Nil);
NSLog(@"Null is %p",NULL);
NSLog(@"nil is %@",nil);
NSLog(@"NSNULL is  %@",kCFNull);

nil is 0x0**
Nil is 0x0**
Null is 0x0**
nil is (null)**
NSNULL is  <null>**

主要的區(qū)別就在 nil 系 和 NSNull系 的區(qū)別

nil : 作為對象的空指針和數(shù)組的結(jié)束標(biāo)志
NSNull:作為數(shù)組中的空值占位符

寫這篇文章我修改了好多次鲁捏,隨著學(xué)習(xí)的深入,有些早期的認(rèn)識是錯(cuò)誤的跋糗健8贰!双揪!
例如這段代碼

    Class class = nil;
    Class class1 = Nil;
    char *p =nil;
    char *p1 = NULL;
    NSString *str = NULL;
    NSLog(@"nil is : %d",class==nil);
    NSLog(@"nil is : %d",class==Nil);
    NSLog(@"Nil is : %d",class1==nil);
    NSLog(@"Nil is : %d",class1==Nil);
    NSLog(@"integer is nil : %d",num == nil);
    NSLog(@"integer is NULL : %d",num == NULL);
    NSLog(@"integer is Nil : %d",num == Nil);
    NSLog(@"nil equals Nil: %d",nil == Nil);
    NSLog(@"Nil equals NULL:%d",p == p1);
    NSLog(@"nil equals NULL: %d",nil == NULL);

結(jié)果全是1动羽,所以這樣看,本質(zhì)上 nil , Nil 和 NULL 是一樣的
-->聰明的你能發(fā)現(xiàn)上面的錯(cuò)誤碼盟榴?曹质??
看下下面這段說明
In Objective-C, it's important that you distinguish between objects and primitive types.
An object is always stored as a pointer, which is the object's location in memory. A pointer is just a number. With NSLog, you can use %p to see this value. You can display it in the debugger too, like this: print myObject. A pointer is displayed as a hexadecimal number, with a 0x
prefix. nil is essentially location zero (0x0000). When you allocate any kind of object, you'll get a pointer which isn't zero. When you assign an object to a variable, you are simply copying the memory address, not duplicating the object. With NSLog, you can use %@ to print out an object's description
. In the debugger, like this: print-object myObject
.
Primitive types like NSInteger
aren't objects. Instead of storing a pointer, usually you just store the value. When you assign an NSInteger
variable, you make a copy of the value. You can see the value in the debugger using print
. Or like this: NSLog("%ld", (long)currentRow)
. When you assign a primitive, you copy its value. Don't use %@
or print-object
with primitives — they expect objects.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市羽德,隨后出現(xiàn)的幾起案子几莽,更是在濱河造成了極大的恐慌,老刑警劉巖宅静,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件章蚣,死亡現(xiàn)場離奇詭異,居然都是意外死亡姨夹,警方通過查閱死者的電腦和手機(jī)纤垂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來磷账,“玉大人峭沦,你說我怎么就攤上這事√釉悖” “怎么了吼鱼?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長绰咽。 經(jīng)常有香客問我菇肃,道長,這世上最難降的妖魔是什么取募? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任琐谤,我火速辦了婚禮,結(jié)果婚禮上玩敏,老公的妹妹穿的比我還像新娘斗忌。我一直安慰自己,他們只是感情好聊品,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布飞蹂。 她就那樣靜靜地躺著,像睡著了一般翻屈。 火紅的嫁衣襯著肌膚如雪陈哑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天伸眶,我揣著相機(jī)與錄音惊窖,去河邊找鬼。 笑死厘贼,一個(gè)胖子當(dāng)著我的面吹牛界酒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嘴秸,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼毁欣,長吁一口氣:“原來是場噩夢啊……” “哼庇谆!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起凭疮,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤饭耳,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后执解,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體寞肖,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年衰腌,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了新蟆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,117評論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡右蕊,死狀恐怖琼稻,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情尤泽,我是刑警寧澤欣簇,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站坯约,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏莫鸭。R本人自食惡果不足惜闹丐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望被因。 院中可真熱鬧卿拴,春花似錦、人聲如沸梨与。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽粥鞋。三九已至缘挽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間呻粹,已是汗流浹背壕曼。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留等浊,地道東北人腮郊。 一個(gè)月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像筹燕,于是被迫代替她去往敵國和親轧飞。 傳聞我的和親對象是個(gè)殘疾皇子衅鹿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容