iOS——nil、Nil、NULL和[NSNull null]的区别

首先我们先来看一下苹果文档上的解释:

  1. nil:Defines the id of a null instance.(定义空实例的id)
  2. Nil:Defines the id of a null class.(定义空类的id)
  3. NULL:Returns the singleton instance of NSNull.(返回NSNull的单例实例)
  4. NSNull:A singleton object used to represent null values in collection objects that don’t allow nil values.(用于表示不允许空值的集合对象中的空值的单例对象)

区别

先看一下它们的打印值:

NSLog(@"%@",nil);
NSLog(@"%@",Nil);
NSLog(@"%@",NULL);
NSLog(@"%@",[NSNull null]);

我们可以看到,前三个的打印值是一样的,而NSNull的打印值不太一样

nil

首先我们先来看nil

定义

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

其中__has_feature(cxx_nullptr)用于判断C++中是否有nullptr特性,对于普通iOS开发者来说,nil的定义形式为:

#   define nil __DARWIN_NULL

就是说nil最终是__DARWIN_NULL的宏定义, __DARWIN_NULL是定义在_types.h中的宏,其定义形式如下:

#ifdef __cplusplus
#ifdef __GNUG__
#define __DARWIN_NULL __null
#else /* ! __GNUG__ */
#ifdef __LP64__
#define __DARWIN_NULL (0L)
#else /* !__LP64__ */
#define __DARWIN_NULL 0
#endif /* __LP64__ */
#endif /* __GNUG__ */
#else /* ! __cplusplus */
#define __DARWIN_NULL ((void *)0)
#endif /* __cplusplus */

非C++代码的 __DARWIN_NULL最终定义形式如下:

#define __DARWIN_NULL ((void *)0)

所以 *nil本质上是:(void )0

用处

用于表示指向Objective-C中对象的指针为空

NSString *string = nil;
id anyObject = nil;

Nil

定义

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

nil和Nil一样,*Nil本质上也是:(void )0

用处

用于表示Objective-C类(Class)类型的变量值为空

Class anyClass = Nil;

NULL

定义

#undef NULL
#ifdef __cplusplus
#  if !defined(__MINGW32__) && !defined(_MSC_VER)
#    define NULL __null
#  else
#    define NULL 0
#  endif
#else
#  define NULL ((void*)0)
#endif

其中__cplusplus表示是不是C++代码,所以对于普通的iOS开发者来说,通常NULL的定义就是:

#  define NULL ((void*)0)

所以,NULL本质上是:(void)0* NULL是C语言发展来的,所以表示的就是空指针

用处

NULL表示C指针为空

charchar *string = NULL;

NSNull

@interface NSNull : NSObject <NSCopying, NSSecureCoding>  + (NSNull *)null;  @end

用处

从定义中可以看出,NSNull是一个Objective-C类,只不过这个类相当特殊,因为它表示的是空值,即什么都不存。它也只有一个单例方法+[NSNUll null]。该类通常用于在集合对象中保存一个空的占位对象。

我们通常在定义NSArray数组时:

NSArray *arr = [NSArray arrayWithObjects:@"wang",@"zhang",nil];

在NSArray中只要遇到了nil,NSArray就会认为数组元素该截止了,即NSArray只关注nil之前的对象,nil之后的对象会被抛弃。比如下面的写法:

NSArray *arr = [NSArray arrayWithObjects:@"wang",@"zhang",nil,@"zhi"];

此时,NSArray就只会保存前两个元素,nil后面的元素就会被舍弃

这种情况,就可以使用NSNull实现:

NSArray *arr = [NSArray arrayWithObjects:@"wang",@"zhang",[NSNull null],@"zhi"];

那么向nil和NSNull发送消息会产生什么样的影响呢?

首先向nil发送消息程序是不会崩溃的

因为OC的函数都是通过objc_msgSend进行消息发送来实现的,相对于C和C++来说,对于空指针的操作会引起crash问题,而objc_msgSend会通过判断self来决定是否发送消息,如果self为nil,那么selector也会为空,直接返回,不会出现问题。视方法返回值,向nil发消息可能会返回nil(返回值为对象),0(返回值为一些基础数据)或0X0(返回值为id)等。
但是如果向NSNull发送消息,那么程序就会崩溃了
对于[NSNull null]对象发送消息时,是会crash的,因为NSNull类只有一个null方法。

关于对nil发送消息unrecognized selector sent to instance会造成程序崩溃的原因:

这是因为这个对象已经被释放了(引用计数为0了),那么这个时候再去调用方法肯定是会Crash的,因为这个时候这个对象就是一个野指针(指向僵尸对象(对象的引用计数为0,指针指向的内存已经不可用)的指针)了,安全的做法是释放后将对象重新置为nil,使它成为一个空指针,大家可以在关闭ARC后手动release对象验证一下。

关于空指针与野指针

空指针:

  1. 没有存储任何地址的指针就是空指针
  2. 空指针就是被赋值为0的指针,在没有被具体初始化之前,其值为0。

野指针:

  1. 指向“垃圾”(不可用内存)内存的指针。

总结空指针与野指针:

  1. 利用野指针发消息特别危险,编译器会报错。也就是说,如果一个对象已经被回收了,就不要再去操作它,不要再尝试给它发消息。
  2. 利用空指针发消息是没有任何问题的

iOS——nil、Nil、NULL和[NSNull null]的区别相关推荐

  1. 【iOS】—— nil、Nil、NULL和NSNull学习

    nil.Nil.NULL和NSNull 文章目录 nil.Nil.NULL和NSNull nil NSNull Nil NULL 总结: 我们先来看看这几个苹果官方文档的解释: nil:Defines ...

  2. iOS开发 nil Nil NULL NSNull 的使用

    nil: A null pointer to an Objective-C object. ( #define nil ((id)0) ) nil 是一个对象值. Nil: A null pointe ...

  3. IOS 学习笔记 2015-03-20 O之 nil,Nil,NULL,NSNull

    1.oc最好 用nil   [ nil  任意方法],不会崩溃  nil 是一个对象值. NULL是一个通用指针(泛型指针). 2. NSNULL,NULL和nil在本质上应该是一样的,NULL和ni ...

  4. ios nil、NULL和NSNull 的使用

    nil用来给对象赋值(Objective-C中的任何对象都属于id类型),NULL则给任何指针赋值,NULL和nil不能互换,nil用于类指针赋值(在Objective-C中类是一个对象,是类的met ...

  5. IOS中类和对象还有,nil/Nil/NULL的区别

    转自:http://blog.sina.com.cn/s/blog_5fb39f910101akm1.html 类与对象的概念 类是对同一类事物高度的抽象,类中定义了这一类对象所应具有的静态属性(属性 ...

  6. (0047)iOS开发之nil/Nil/NULL的区别

    小结: 1.oc最好用nil   [ nil  任意方法],不会崩溃 nil是一个对象值. NULL是一个通用指针(泛型指针). 2. NSNULL,NULL和nil在本质上应该是一样的,NULL和n ...

  7. Objective C 中的nil,Nil,NULL和NSNull理解

    kenyo网友的原创说法是:做IOS开发的估计都对Objective-C的内存管理机制很头疼,一不小心程序就会出内存泄露,我也不例外,前几天被指针的置nil与release给搞惨了,今和大家详细解说一 ...

  8. iOS中nil Nil NULL 区别

    为什么80%的码农都做不了架构师?>>>    一.nil 当一个对象置为nil时,这个对象的内存地址就会被系统收回.置空之后是不能进行retain,copy等跟引用计数有关的任何操 ...

  9. 关于nil和 null和NSNull的相关问题

    2019独角兽企业重金招聘Python工程师标准>>> 关于nil和 null和NSNull的区别及相关问题 1.nil和null从字面意思来理解比较简单,nil是一个对象,而NUL ...

最新文章

  1. hibernate中的hql查询语句list查询所有与iterate查询所有的区别
  2. 提升大学社团管理工具--轻雀协作
  3. 【Node.js】2.开发Node.js选择哪个IDE 开发工具呢
  4. centos6.3下yum安装redis
  5. python专科就业难吗-python好就业吗
  6. java中pi_Java-Pi的几种实现
  7. sizeWithFont 不是线程安全。
  8. MyEclipse/Eclipse中properties文件中文乱码问题解决
  9. wps怎么免费导出简历_简历模板Word文档 免费下载简历模板
  10. 【错误记录】Ubuntu 编译 ffmpeg 报错 ( nasm/yasm not found or too old. Use --disable-x86asm for a crippled bu )
  11. 智慧社区解决方案上线!给社区装上智能大脑
  12. 20222817《Linux内核原理与分析》第五周作业
  13. 简单的蜜罐以及开源蜜罐HFish的安装与配置
  14. 使用计算机编辑文档的同时,小学信息技术2-2-用计算机编辑文档(北京版).doc
  15. 擦窗机器人不用时怎么收纳_擦窗机器人如何保证不会高空掉落,这些措施必不可少...
  16. 【自动化】火车头采集器
  17. SpringBoot 整合实现ActiveMQ
  18. 广电BOSS系统的建设原则
  19. JAVA17版本_我的世界JAVA版1.17版本内容预览
  20. 关于事物型数据库的索引原理

热门文章

  1. 什么是高防IP以及私服被攻击了的处理方案
  2. Linux at,crontab的使用以及apache的安装以及访问
  3. halcon 阈值分割
  4. 许巍·此时此刻2014全球巡演济南站
  5. CF464D World of Darkraft - 2
  6. 苹果M1芯片兼容mysql吗_Apple M1芯片电脑 软件兼容情况
  7. 【去雨】Self-Learning Video Rain Streak Removal: When Cyclic Consistency Meets Temporal Correspondence
  8. 最优化理论与方法学习笔记
  9. Inno Setup学习心得(2)
  10. 赣州农校计算机网络技术,赣州农校的“农科类专业”前途怎么样?