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指针不指向任何对象.