Objective-C 中 nil、NIL 和 null 之间的区别

Posted

技术标签:

【中文标题】Objective-C 中 nil、NIL 和 null 之间的区别【英文标题】:Difference between nil, NIL and, null in Objective-C 【发布时间】:2011-05-06 08:45:21 【问题描述】:

我想知道nilNILnull 之间的区别。 我搜索了一下,发现了这个:

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

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

null -> 指向原始类型的空指针或缺少数据

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

请给我解释一下。另外,Objective-C 中有没有像 NSNullNSNil 这样的词?如果是这样,请解释它的用途。

【问题讨论】:

Objective-C 对象是Objective-C 类的一个实例(通过@interface 声明的类)。该实例通常使用 [[MyClass alloc] init] 或 [MyClass new] 创建。 在 ObjC 中,对象和类之间的区别与任何其他语言中的相同。如果你不知道 - 你应该学习 OOP 基础知识。 【参考方案1】:

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

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

if (anotherObject == nil) // do something

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

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

NULL 是任意 C 指针的文字空值。例如,

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

NSNull 是代表 null 的对象的类。实际上,只有一个对象,即+[NSNull null] 返回的对象。它与nil 不同,因为nil 是文字空值,即它不是对象。另一方面,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 中没有这样的东西。

【讨论】:

您还应该注意,可以向nil 发送消息而不会出现分段错误。 很好的解释谢谢。但我想问一下,我们可以将 NULL 用于目标 C 对象吗?喜欢---> id mYobj = NULL ?? 这可以反映到swift吗?就像,在 swift 中是否有相应的对应关系?【参考方案2】:

我不确定,但我认为 nil 应该只用来代替 id,Java 和 C++ 程序员会将 pointer 视为 object。对非对象指针使用NULL

nil 通常用于 Objective-C 对象类型,而NULL 用于 c 样式指针

【讨论】:

这是正确的。我认为在实践中,你使用哪个并不重要。但要遵守约定。 约定很有用,但很高兴知道 nil 和 NULL 和 Nil 对编译器都是一样的。【参考方案3】:

Nil、Null 和 nil 与下面一起使用

1> 用于 Objective c 类的 Nil

2> 目标 c 对象为零

3> C 指针为空

示例:

1>A 类=无;

2>NSString strName=nil;

3>char *pointerChar = NULL;

【讨论】:

优雅的榜样哥们【参考方案4】:

假设你有一个班级MyClass 然后按照约定,如果要将其实例初始化为空值,则使用 nil(与 java 中的 null 相同) 即

MyClass *obj = nil;

如果你想初始化一个指向 null 值的原始指针(与 c 相同),你可以使用

int *ptr = NULL; 

如果您想初始化为 Class 对 null 值的引用(与 java 中的 null 相同),请使用

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_NULL_types.h中的定义

#define __DARWIN_NULL ((void *)0)

所以逻辑上没有区别。这里的主要思想是将CObjective-C的指针初始化为0。如果你知道C,那么你可以分配

int *ptr = 0;

没有将0 类型转换为指针。因为您无需对0 进行类型转换即可将其分配给指针。

简而言之,它们都是0,仅此而已。

【讨论】:

Java 的 NULL 是小写的:null【参考方案5】:

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

所有这三个值都表示空值或零指针值。这 区别在于 NULL 表示 任何指针的零, nil 是 特定于对象(例如,id)和 Nil 特定于 类指针。 使用正确的 null 应该被认为是一种最佳实践 出于文档目的,在适当的情况下反对,甚至 尽管没有什么可以阻止某人混合和匹配 他们一起去。

以下链接可能对您有所帮助:

http://nshipster.com/nil/

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

【讨论】:

【参考方案6】:

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

NSNull

NSArrayNSDictionary 这样的集合不能包含 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 对象的文字空值

Nil (Class)0 Objective-C 类的文字空值

【讨论】:

以上是关于Objective-C 中 nil、NIL 和 null 之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

给定 nil 参数时要做啥的 Objective-c 约定?

objective-C nil,Nil,NULL之间的不同

Json在objective-c中解析nil字段

NSNumber如何? == nil 在运行时在 Objective-C 中提交?

Objective-c:自定义类实例作为字典键,当键存在时返回 nil

尝试在objective-c中从objects[0]插入nil对象