標(biāo)識(shí) | 值 | 含義 |
---|---|---|
Null | (void*)0 | C指針的字面零值 |
nil | (id)0 | ObjC對象的字面零值 |
Nil | (Class)0 | ObjC類的字面零值 |
NSNull | [NSNull null] | 用來表示零值的單獨(dú)對象 |
NOTICE: 蘋果的編譯器在編譯時(shí)會(huì)生成objc_msgSend這樣的方法來發(fā)送消息娘荡,當(dāng)對象設(shè)置為nil時(shí)灭翔,它就不會(huì)去尋找是哪個(gè)類實(shí)例的消息隙咸,因此什么也不干账千,這是蘋果的處理方式。
若obj為nil:[obj message]將返回NO,而不是NSException
若obj為NSNull:[obj message]將拋出異常NSException
nil绳军、Nil印机、NULL的使用對比
先看下面做的一個(gè)實(shí)驗(yàn):
NSArray * array = [NSArray arrayWithObjects:@"good", @"morning", nil];
// array = nil; // 輸出:0
// array = NULL; // 輸出:0
// array = Nil; // 輸出:0
NSLog(@"%ld", array.count);// 分別使用上面三句注釋的語句,輸出值無區(qū)別
Class class = [NSURL class];
// class = Nil; // 輸出:(null)
// class = nil; // 輸出:(null)
// class = NULL; // 輸出:(null)
NSLog(@"%@", class); // 分別使用上面三句注釋的語句门驾,輸出值無區(qū)別
int a = 10; int * p = &a;
// p = NULL; // 輸出:0x0
// p = nil; // 輸出:0x0//
p = Nil; // 輸出:0x0
NSLog(@"%p", p); // 分別使用上面三句注釋的語句射赛,輸出值無區(qū)別
結(jié)論:
- nil、Nil奶是、NULL在使用上是沒有什么區(qū)別的楣责,但是程序員的一個(gè)約定:C結(jié)構(gòu)的指針使用NULL;對象指針使用nil聂沙;類對象指針使用Nil秆麸。
- 另外NSNull和nil、Nil及汉、NULL具有本質(zhì)上的區(qū)別沮趣。NSNull是一個(gè)對象,而nil坷随、Nil房铭、NULL只是給指針賦空值驻龟。
- 在另外,給一個(gè)賦值為nil的對象發(fā)送消息缸匪,不會(huì)產(chǎn)生異常翁狐。當(dāng)然給一個(gè)賦值為Nil、NULL的對象發(fā)送消息也不會(huì)產(chǎn)生異常凌蔬,這個(gè)在例子中已經(jīng)證實(shí)露懒。故根據(jù)此條結(jié)論的總結(jié)為:nil、Nil砂心、NULL目的都是給一個(gè)指針賦值為空隐锭,給空指針發(fā)送消息不會(huì)產(chǎn)生異常
NSNull 到底是個(gè)什么東西?我從來沒有調(diào)用過這個(gè)類计贰,那么它又是哪產(chǎn)生的?
- 通過 search 和排查蒂窒,我最終定位了這個(gè)問題躁倒,這個(gè) NSNull 是由 AFNetworking 的一個(gè)函數(shù)回調(diào)產(chǎn)生的:
- 我在取 responseObject 的某個(gè) value 時(shí),得到了一個(gè) NSNull 對象洒琢,而這個(gè)對象本應(yīng)該是一個(gè) NSString 的秧秉。
- 通過與 PHP 服務(wù)器同學(xué)聯(lián)調(diào),我們最終發(fā)現(xiàn)了這個(gè)問題產(chǎn)生的原因衰抑。
- 原來象迎,服務(wù)器同學(xué)在獲取某個(gè)字段的時(shí)候,不小心填錯(cuò)了參數(shù)呛踊,導(dǎo)致獲取到的字段為空砾淌。他將這個(gè)空作為這個(gè) Key 的 Value 填入了 JSON。
- iOS APP 這邊谭网,AFNetworking 發(fā)現(xiàn)了這個(gè)空汪厨,它跟 Objective-C 中的 nil 有著顯著的區(qū)別,因?yàn)?Objective-C 中的 NSDictionary 是不允許某一個(gè) Key 對應(yīng)的 Value 為 nil的愉择。 這個(gè)空劫乱,最終被轉(zhuǎn)化成了一個(gè) NSNull 對象。
nil锥涕、Nil衷戈、NULL、NSNull之間的區(qū)別
nil的含義
指向一個(gè)對象的指針為空层坠,用于給對象指針賦值為空殖妇,防止野指針的產(chǎn)生;也稱nil為空對象:表示一個(gè)已經(jīng)被釋放了的對象窿春,和值為空的對象(NSNull)不同拉一。NSNull是一個(gè)對象采盒,只不過這個(gè)對象的值為空
#ifndef nil
# if __has_feature(cxx_nullptr)
# define nil nullptr
# else
# define nil __DARWIN_NULL
# endif
#endif
給對象指針賦值為空:
NSString * name = nil;
NSString * url = nil;
id object = nil;
Nil的含義
指向一個(gè)類的指針為空,用于給類對象指針賦值為空
#ifndef Nil
# if __has_feature(cxx_nullptr)
# define Nil nullptr
# else
# define Nil __DARWIN_NULL
# endif
#endif
給類對象賦值為空:
Class class = Nil;
NULL的含義
指向C類型的指針蔚润,用于給C類型的指針賦值為空
#if defined(__need_NULL)
#undef NULL
#ifdef __cplusplus
# if !defined(MINGW32) && !defined(_MSC_VER)
# define NULL __null
# else
# define NULL 0
# endif
#else
# define NULL ((void*)0)
#endif
給C類型指針賦值:
int * a = NULL;
char * ch = NULL;
struct aStruct = NULL;
NSNull的含義
NSNull是一個(gè)類磅氨,其繼承自NSObject,只擁有一個(gè)類方法嫡纠。實(shí)例對象表示這是一個(gè)內(nèi)容為空的對象烦租。主要用于數(shù)組、字典除盏。
NSMutableArray * mArray = [NSMutableArray array];
[mArray addObject:[NSNull null]];
NSLog(@"%@", [mArray firstObject]); // 輸出為:<null>
NSMutableDictionary * dict = [NSMutableDictionary dictionary];
[dict setObject:[NSNull null] forKey:@"null"];
NSLog(@"%@", dict[@"null"]); // 輸出為:<null>
由此可見叉橱,可用NSNull的實(shí)例對象在數(shù)組、字典中占位者蠕,其所占有的位置為空窃祝。