nil、Nil、NULL、NSNull之間的區別
nil的含義
指向一個對象的指針為空,用于給對象指針賦值為空,防止野指針的產生;也稱nil為空對象:表示一個已經被釋放了的對象,和值為空的對象(NSNull)不同。NSNull是一個對象,只不過這個對象的值為空
#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的含義
指向一個類的指針為空,用于給類對象指針賦值為空
#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是一個類,其繼承自NSObject,只擁有一個類方法。實例對象表示這是一個內容為空的對象。主要用于數組、字典。
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的實例對象在數組、字典中占位,其所占有的位置為空。
nil、Nil、NULL的使用對比
先看下面做的一個實驗:
NSArray * array = [NSArray arrayWithObjects:@"good", @"morning", nil];
// array = nil; // 輸出:0
// array = NULL; // 輸出:0
// array = Nil; // 輸出:0
NSLog(@"%ld", array.count);
// 分別使用上面三句注釋的語句,輸出值無區別
Class class = [NSURL class];
// class = Nil; // 輸出:(null)
// class = nil; // 輸出:(null)
// class = NULL; // 輸出:(null)
NSLog(@"%@", class);
// 分別使用上面三句注釋的語句,輸出值無區別
int a = 10;
int * p = &a;
// p = NULL; // 輸出:0x0
// p = nil; // 輸出:0x0
// p = Nil; // 輸出:0x0
NSLog(@"%p", p);
// 分別使用上面三句注釋的語句,輸出值無區別
結論:
1> nil、Nil、NULL在使用上是沒有什么區別的,但是程序員的一個約定:C結構的指針使用NULL;對象指針使用nil;類對象指針使用Nil。
2> 另外NSNull和nil、Nil、NULL具有本質上的區別。NSNull是一個對象,而nil、Nil、NULL只是給指針賦空值。
3> 在另外,給一個賦值為nil的對象發送消息,不會產生異常。當然給一個賦值為Nil、NULL的對象發送消息也不會產生異常,這個在例子中已經證實。故根據此條結論的總結為:nil、Nil、NULL目的都是給一個指針賦值為空,給空指針發送消息不會產生異常