nil / Nil / NULL / NSNull ? 傻傻分不清楚

NULL算是属于C语言中的空指针。

Objective-C在C的表达不存在的基础上增加了nil。nil是一个指向为空的对象指针。虽然它在语义上与NULL不同,但是在技术层面上来说,它们是相等的。

在Foundation/NSObjCRuntime.h中,Nil被定义为指向为空的类指针,这个Nil并不经常会使用到,但也值得注意。

在框架层面,Foundation定义了NSNull,即一个类方法+null,它返回一个单独的NSNull对象。NSNull与nil以及NULL不同,因为它是一个实际的对象,而不是一个空值。

nil

刚被分配的NSObject的内容被设置为空。也就是说那个对象所有的指向其他对象的指针都从nil开始,所以在init方法中将变量初始化为 nil 的表达是没有必要的。nil最为显著的特点其实是它虽然为空,但是当向nil发送消息时,程序不会有异常,会继续执行下去

// 举个例子,这个表达
if (name != nil && [name isEqualToString:@"Tom"]) { ... }
// 可以简化为:
if ([name isEqualToString:@"Tom"]) { ... }

需要注意Array和Dictionary使用nil的情况。在使用NSArray的+ arrayWithObjects:-initWithObjects:以及NSDictionary的+ dictionaryWithObjectsAndKeys:- initWithObjectsAndKeys:这些标记为 NS_REQUIRES_NIL_TERMINATION 的方法时,nil是被当成最后一个参数的,出现在nil后面的参数都会被忽略掉。比如:

NSArray *arr = [ NSArray arrayWithObjects:@ 1 , @ 2 , nil , @ 3 ];
NSLog ( @"arr = %@" , arr);

这个数组对象arr其实只有@1和@2两个元素,@3已经被截掉了。

Nil

nil表示空的实例(instance),而这个开头字母大写的Nil则表示空的类(class),判断某个Class是否为空,语意上应该用Nil。

NULL

绝大多数情况下,nil、Nil和NULL可以代替使用,但是在语意上,当某个API想要传入某个指针(void *),而不是id类型时,最好还是传入NULL,以此保持了Objective-C严谨的定义。比如NSArray的这个API,argument要求的是id,所以传入nil会比较好。

- (void)makeObjectsPerformSelector:(SEL)aSelector withObject:(nullable id)argument 

而像NSMutableArray的sortUsingFunction:context:

- (void)sortUsingFunction:(NSInteger (*)(ObjectType, ObjectType, void * __nullable))compare context:(nullable void *)context;

在这里,context传入NULL会比传入nil好。

NSNull

NSNull在Foundation和其它框架中被广泛的使用,以解决如NSArray和NSDictionary之类的集合不能有nil值的缺陷。

NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionary];
mutableDictionary[@"someKey"] = [NSNull null];
NSLog(@"Keys: %@,mutableDictionary = %@", [mutableDictionary allKeys],mutableDictionary); 

打印的结果如下:可以看出字典mutableDictionary有一个元素,该元素的key值为someKey,其对应的value为null。

result.png

如果将上面的代码改为:

...mutableDictionary[@"someKey"] = nil;
NSLog(@"Keys: %@,mutableDictionary = %@", [mutableDictionary allKeys],mutableDictionary); 

此时,打印出来的Keys和mutableDictionary的值是空的,什么也没有!所以NSNull在这个字典里充当一个占位符,表示没有

NULL、nil、Nil、NSNull的区别

标志 含义
NULL (void *) 0 C指针的字面零值
nil (id) 0 Objective-C对象的字面零值
Nil (Class ) 0 Objective-C类的字面零值
NSNull [NSNull null] 用来表示零值的单独的对象

参考:
[http://nshipster.cn/nil/]

你可能感兴趣的:(nil / Nil / NULL / NSNull ? 傻傻分不清楚)