Objective-C中nil,NIL和null之间的差异


71

我想知道的区别nilNILnull。我四处搜寻,发现了这一点:

nil ->指向Objective-C对象的空指针

NIL ->指向Objective-C类的空指针

null ->指向原始类型或没有数据的空指针

但是我无法清楚地理解术语“ Objective-C对象”和“类”。

请给我解释一下。此外,有没有像任何文字NSNullNSNil在Objective-C?如果是这样,请说明其用途。


一个Objective-C对象是一个Objective-C类的实例(通过@interface声明的一个实例)。该实例通常使用[[MyClass alloc] init]或[MyClass new]创建。
MKroehnert 2011年

在ObjC中,对象和类之间的区别与任何其他语言相同。如果您不知道,则应该学习OOP基础知识。
Eimantas 2012年

Answers:


151

nil是Objective-C对象的文字空值,对应于抽象类型id或通过声明的任何Objective-C类型@interface。例如:

NSString *someString = nil;
NSURL *someURL = nil;
id someObject = nil;

if (anotherObject == nil) // do something

Nil是Objective-C类的文字空值,对应于type Class。由于大多数代码不需要变量来引用类,因此其用法并不常见。一个例子是:

Class someClass = Nil;
Class anotherClass = [NSString class];

NULL是任意C指针的原义null值。例如,

int *pointerToInt = NULL;
char *pointerToChar = NULL;
struct TreeNode *rootNode = NULL;

NSNull是代表null的对象的类。实际上,只有一个对象,即由返回的对象+[NSNull null]。它不同于nil因为nil是文字上的null值,即它不是对象。NSNull另一方面,的单个实例是一个适当的对象。

NSNull通常在Foundation集合中使用,因为它们无法存储nil值。对于字典,-objectForKey:返回nil表示给定键在字典中没有对应的对象,即该键尚未添加到字典中。如果要明确表明您具有某个键,但还没有值,可以使用[NSNull null]

例如,以下内容引发异常,因为字典无法存储nil值:

NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:nil forKey:@"someKey"];

另一方面,以下代码是有效的,因为[NSNull null]它是非nil对象:

NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:[NSNull null] forKey:@"someKey"];

值得一提的是,Foundation集合具有一些初始化程序,这些初始化程序nil用作对象列表结尾的标记,而不必指定列表中元素的数量。只能由于nil无法存储在Foundation集合中而发生这种情况。例如,

NSArray *array = [NSArray arrayWithObjects:@"one", @"two", nil];

至于NILNSNil,在Objective-C或Apple Foundation中都没有。


9
您还应该注意,可以将消息发送到nil而不会遇到分段错误。
MKroehnert 2011年

1
很好的解释,谢谢。但我想问一下,我们可以对目标C对象使用NULL吗?像---> id mYobj = NULL ??
Vishal Singh

这可以体现出来吗?像那样,迅速对应吗?
卡拉·卡马戈

7

我不知道,但我认为nil应该只在地方的使用id,什么样的Java和C ++程序员会认为作为pointer一个object。使用NULL非对象指针。

nil通常用于Objective-C对象类型,而NULL用于C风格的指针


1
这是对的。我认为在实践中,使用哪个并不重要。但是请遵循惯例。
nielsbot'5

约定很有用,但是很高兴知道nil和NULL以及Nil对编译器都是相同的。
David Casseres


5

假设您有一个类,MyClass 然后nil如果您想将其实例初始化为null值(与nullJava中相同),则按惯例使用

MyClass *obj = nil;


如果要初始化指向空值的原始指针(与c中相同),请使用

int *ptr = NULL; 


如果要初始化以Class引用空值(与nullJava中相同),请使用

Class classRefOfMyClass = Nil;

这只是一个约定,否则Nil或nil具有相同的含义,也许NULL,nil或Nil都相同。

这是objc.h文件中这些的定义

#ifndef Nil
# if __has_feature(cxx_nullptr)
#   define Nil nullptr
# else
#   define Nil __DARWIN_NULL
# endif
#endif

#ifndef nil
# if __has_feature(cxx_nullptr)
#   define nil nullptr
# else
#   define nil __DARWIN_NULL
# endif
#endif

而在 stddef.h

#define NULL ((void*)0)

以及__DARWIN_NULLin中的定义_types.h

#define __DARWIN_NULL ((void *)0)

因此,逻辑上没有区别。这里的主要思想是初始化一个指针是否C还是Objective-C0。如果您有知识,C则可以分配

int *ptr = 0;

没有类型转换0为指针。由于您无需强制转换0即可将其分配给指针。

简而言之,它们都是0,别无其他。


1
JavaNULL是小写字母:null
Victor Zamanian

2

这将帮助您了解nil,NIL和null之间的区别。

这三个值全部代表空值或零指针值。区别在于,尽管NULL表示任何指针为零,但 nil特定于对象(例如,id),而Nil特定于类指针。 即使在没有什么阻止某人进行混合和匹配的情况下,在正确的情况下在正确的情况下使用正确的空对象也应视为一种最佳实践。

以下链接可能会以某种方式为您提供帮助:

http://nshipster.com/nil/

这是链接中的一些重要部分:

在此处输入图片说明


1

nil,NIL和null。取决于您的要求。

NSNull

集合喜欢NSArray并且NSDictionary不能包含nil值。

NSMutableDictionary *MymutableDictionary = [NSMutableDictionary dictionary];
MymutableDictionary[@"someKey"] = [NSNull null]; // Sets value of NSNull singleton for "someKey"
NSLog(@"Keys: %@", [mutableDictionary allKeys]);

该对象指向其他对象的所有指针均以nil开头,因此不必在init方法中设置self。(association)= nil。

在其他语言中,例如C ++,这会使您的程序崩溃,但是在Objective-C中,对nil调用方法将返回零值。

if (name != nil)
{
........
}

符号值含义

nil(id)0 Objective-C对象的文字空值

目标C类的Nil(Class)0文字空值

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.