Objective C 中的nil,Nil,NULL和NSNull理解
kenyo网友的原创说法是:做IOS开发的估计都对Objective-C的内存管理机制很头疼,一不小心程序就会出内存泄露,我也不例外,前几天被指针的置nil与release给搞惨了,今和大家详细解说一下有关Objective-C中nil与release的区别与用法。
首先说一下他们两的作用,nil就是把一个对象的指针置为空,只是切断了指针与内存中对象的联系,它对内存的释放没有什么作用;而release才是真正用于内存释放的,release后系统会将该块内存标记为可用(可重新分配)。所以nil并没有释放内存,只有release才是真正释放内存。
二者使用顺序,如果没有release就直接nil,那么虽然不会出错(release一个空指针是合法的),但却等于自己制造了内存泄漏,因为nil之后release就已经不起作用了,我之前的教训就是一不小心把nil搁在了release之前,所以leak一直报内存泄露。
相反,如果先release后设置nil,就不会出现这样的问题,但是有人就会问,release而没有设置nil,会怎样?其实程序可能也不会报错,但是要知道设置nil其实是为了防止指针错乱,因为一个对象在release之后,给它所分配的内存就已经被释放了,如果释放之后不把指针置空的话,系统再误用到到这个指针时,那么程序就会崩溃(此种情况特别容易出现在延时调用函数中),如果释放之后把它的指针置为空,则即便后面的程序用到该指针,也不会崩溃。所以Objective-C释放内存时必须先release然后nil。
还有一点,在子龙山人的原创文章中有这样的话:可能有读者经常看到,在我的教程的dealloc函数里面有这样的代码:self.xxx = nil;看到这里,现在你们明白这样写有什么用了吧?它等价于[xxx release]; xxx = [nil retain];(---如果你的property(nonatomic,retian)xxx,那么就会这样,如果不是,就对号入座吧)。这就是说,在使用了@property运算符后的类变量会产生set和get方法,而set方法的具体写法是这样的:
-(void) setNames:(NSArray*)names{
NSLog(@"setNames");
if (_name != name) {
[_name release];
_name = [name retain]; }
}
原来的变量和nil比较,不等于就自动释放了,然后再执行xxx=[nil retain];语句
nil
- nil 是 ObjC 对象的字面空值,对应 id 类型的对象,或者使用 @interface 声明的 ObjC 对象。
- 例如:
NSString *someString = nil;
NSURL *someURL = nil;
id someObject = nil;
if
(anotherObject == nil)
// do something
- 定义:
// objc.h
#ifndef nil
# if __has_feature(cxx_nullptr)
# define nil nullptr
# else
# define nil __DARWIN_NULL
# endif
#endif
// __DARWIN_NULL in _types.h
#define __DARWIN_NULL ((void *)0)
Nil
- Nil 是 ObjC 类类型的书面空值,对应 Class 类型对象。
- 例如:
Class someClass = Nil;
Class anotherClass = [NSString
class
];
- 定义声明和 nil 是差不多的,值相同:
// objc.h
#ifndef Nil
# if __has_feature(cxx_nullptr)
# define Nil nullptr
# else
# define Nil __DARWIN_NULL
# endif
#endif
NULL
- NULL 是任意的 C 指针空值。
- 例如:
int
*pointerToInt = NULL;
char
*pointerToChar = NULL;
struct
TreeNode *rootNode = NULL;
- 定义:
// in stddef.h
#define NULL ((void*)0)
NSNull
- NSNull 是一个代表空值的类,是一个 ObjC 对象。实际上它只有一个单例方法:+[NSNull null],一般用于表示集合中值为空的对象。
- 例子说明:
// 因为 nil 被用来用为集合结束的标志,所以 nil 不能存储在 Foundation 集合里。
NSArray *array = [NSArray arrayWithObjects:@
"one"
, @
"two"
, nil];
// 错误的使用
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:nil forKey:@
"someKey"
];
// 正确的使用
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:[NSNull null] forKey:@
"someKey"
];
- 定义:
/* NSNull.h
Copyright (c) 1994-2012, Apple Inc. All rights reserved.
*/
#import <Foundation/NSObject.h>
@interface NSNull : NSObject <NSCopying, NSSecureCoding>
+ (NSNull *)null;
@end
NIL 或 NSNil
ObjC 不存在这两个符号!
小结
虽然 nil, Nil, NULL 的值相同,理解它们之间的书面意义才重要,让代码更加明确,增加可读性。
参考资料
object c 中的BOOL值与bool值
typedef signed char BOOL;
#define YES (BOOL) 1
#define NO (BOOL) 0
从上面的定义我们发现布尔变量的值为 YES/NO,或 1/0 。YES 或 1 代表真,NO 或 0 代表假。比如你定义了一个布尔变量并赋了值:
BOOL enabled = NO;
enabled = 0;
判断BOOL值为YES:
if(enabled == YES){
}
或者YES可以省略
if(enabled){
}
判断BOOL值为NO:
if(!enabled){
}
或者
if(enabled != YES){
}
Objective C 中的nil,Nil,NULL和NSNull理解的更多相关文章
- [BS-22] Objective-C中nil、Nil、NULL、NSNull的区别
Objective-C中nil.Nil.NULL.NSNull的区别 1.定义: nil: OC语言定义:#define nil __DARWIN_NULL / #define __D ...
- OC中的野指针,空指针,nil,Nil,NULL,NSNULL小结
周末与一个老朋友吃饭聊天,因为他正在培训班学习iOS开发,就随便聊了几句,发现自己OC基础上的欠缺和一些知识点的混淆.特此整理如下. 1.空指针 没有存储任何内存地址的指针就称为空指针(NULL指针) ...
- iOS 中nil,Nil,NULL,NSNull的区别
类与对象的概念 类是对同一类事物高度的抽象,类中定义了这一类对象所应具有的静态属性(属性)和动态属性(方法). 对象是类的一个实例,是一个具体的事物. 类与对象是抽象与具体的关系. 类其实就是一种数据 ...
- Objective-C数据类型之id,SEL,BOOL,nil,NULL和NSNull
id id是指向Objective-C对象的指针,等价于C语言中的void*,可以映射任何对象指针指向他,或者映射它指向其他的对象.常见的id类型就是类的delegate属性. SEL SEL类型是 ...
- nil、Nil、NULL和NSNull的理解
http://blog.sina.com.cn/s/blog_4930f8e60101h71b.html 其实早就想研究一下nil.Nil.NULL和NSNull之间的区别,只是工作上除了nil,其它 ...
- 1.import和include区别 2.NSLog 和printf区别 3.创建对象做的事情 4. 类和对象方法比较 5 匿名对象优缺点 6. 封装 7.作用域范围 8.id和instancetype 9.自定义构造方法规范 10.nil和Nil及NULL、NSNull区别
1.import和include的区别: import可以防止头文件的重复包含 2.NSLog 和printf的区别: 1,NSLog可以自动换行, 输出调试信息, printf不能. 2,NSLog ...
- Objective C语言中nil、Nil、NULL、NSNull的区别
以下内容是基于搜集整理的网上资料,供参考. nil:指向Objective C语言中对象的空指针,其定义值为(id)0. Nil:指向Objective C语言中类(Class)的空指针,其定义值为( ...
- iOS中nil、Nil、NULL、NSNull详解(转)
ObjC 里面的几个空值符号经常会差点把我搞死,这些基础的东西一点要弄清楚才行,以提高码农的基本素质. nil nil 是 ObjC 对象的字面空值,对应 id 类型的对象,或者使用 @interfa ...
- iOS中nil、Nil、NULL、NSNull详解
nil nil 是 ObjC 对象的字面空值,对应 id 类型的对象,或者使用 @interface 声明的 ObjC 对象. 例如: NSString *someString = nil; NSUR ...
随机推荐
- JS 函数的基本练习
// - 求3个数中的最大值 function biJiao3(x, y, z) { return x > y ? (x > z ? x : z) : (y > z ? y : z) ...
- K3 Wise 常用表【转载】
在后台数据库ICClassType表中,字段FID<0的是老单,FID>0的是新单.--事务类型select * from ICClassType where FT ...
- Domoticz 中接入斐讯 M1 空气质量检测仪
前言 M1 是翻车讯出的一款空气质量检测仪,如今斐讯的服务器经常连不上了,M1 不动动手接到 Domoticz 怕是变成摆设了.教程参考了这里和官方的 Using Python plugins. 步骤 ...
- pyc和pycodeobject
Python是一个先编译再解释的语言. 执行过程:先寻找pyc文件,找到则载入,没找到则把编译的结果保存在pycodeobject中,运行结束则写到pyc文件中
- docker 使用save和load命令来转移image
——假设一个image叫ubuntu—— 在本机执行sudo docker save -o ubuntu.tar ubuntu 由此得到了 ubuntu.tar 文件,将其拷贝到远程机器,执行 sud ...
- Mock单元测试
/// <summary> /// 普通插入 /// </summary> [Fact] public void InsertOrder_Tests() { _sqlMappe ...
- 自动判断文本文件编码来读取文本文件内容(.net版本和java版本)
.net版本 using System; using System.IO; using System.Text; namespace G2.Common { /// <summary> / ...
- [转] Node.js的线程和进程
[From] http://www.admin10000.com/document/4196.html 前言 很多Node.js初学者都会有这样的疑惑,Node.js到底是单线程的还是多线程的?通过本 ...
- MYSQL常用查命令
MYSQL常用查命令 mysql> select version(); 查看MySQL的版本号 mysql> select current_date(); 查看 ...
- (转)求有向图的强连通分量个数(kosaraju算法)
有向图的连通分量的求解思路 kosaraju算法 逛了很多博客,感觉都很难懂,终于找到一篇能看懂的,摘要记录一下 原博客https://www.cnblogs.com/nullzx/p/6437926 ...