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 【问题描述】:我想知道nil
、NIL
和null
之间的区别。
我搜索了一下,发现了这个:
nil
-> 指向 Objective-C 对象的空指针
NIL
-> 指向 Objective-C 类的空指针
null
-> 指向原始类型的空指针或缺少数据
但我无法清楚地理解“Objective-C 对象”和“类”这两个术语。
请给我解释一下。另外,Objective-C 中有没有像 NSNull
或 NSNil
这样的词?如果是这样,请解释它的用途。
【问题讨论】:
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];
至于NIL
或NSNil
,在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)
所以逻辑上没有区别。这里的主要思想是将C
或Objective-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
像 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 对象的文字空值
Nil (Class)0 Objective-C 类的文字空值
【讨论】:
以上是关于Objective-C 中 nil、NIL 和 null 之间的区别的主要内容,如果未能解决你的问题,请参考以下文章
给定 nil 参数时要做啥的 Objective-c 约定?
NSNumber如何? == nil 在运行时在 Objective-C 中提交?