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理解的更多相关文章

  1. [BS-22] Objective-C中nil、Nil、NULL、NSNull的区别

    Objective-C中nil.Nil.NULL.NSNull的区别 1.定义: nil:      OC语言定义:#define nil __DARWIN_NULL   /  #define __D ...

  2. OC中的野指针,空指针,nil,Nil,NULL,NSNULL小结

    周末与一个老朋友吃饭聊天,因为他正在培训班学习iOS开发,就随便聊了几句,发现自己OC基础上的欠缺和一些知识点的混淆.特此整理如下. 1.空指针 没有存储任何内存地址的指针就称为空指针(NULL指针) ...

  3. iOS 中nil,Nil,NULL,NSNull的区别

    类与对象的概念 类是对同一类事物高度的抽象,类中定义了这一类对象所应具有的静态属性(属性)和动态属性(方法). 对象是类的一个实例,是一个具体的事物. 类与对象是抽象与具体的关系. 类其实就是一种数据 ...

  4. Objective-C数据类型之id,SEL,BOOL,nil,NULL和NSNull

     id id是指向Objective-C对象的指针,等价于C语言中的void*,可以映射任何对象指针指向他,或者映射它指向其他的对象.常见的id类型就是类的delegate属性. SEL SEL类型是 ...

  5. nil、Nil、NULL和NSNull的理解

    http://blog.sina.com.cn/s/blog_4930f8e60101h71b.html 其实早就想研究一下nil.Nil.NULL和NSNull之间的区别,只是工作上除了nil,其它 ...

  6. 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 ...

  7. Objective C语言中nil、Nil、NULL、NSNull的区别

    以下内容是基于搜集整理的网上资料,供参考. nil:指向Objective C语言中对象的空指针,其定义值为(id)0. Nil:指向Objective C语言中类(Class)的空指针,其定义值为( ...

  8. iOS中nil、Nil、NULL、NSNull详解(转)

    ObjC 里面的几个空值符号经常会差点把我搞死,这些基础的东西一点要弄清楚才行,以提高码农的基本素质. nil nil 是 ObjC 对象的字面空值,对应 id 类型的对象,或者使用 @interfa ...

  9. iOS中nil、Nil、NULL、NSNull详解

    nil nil 是 ObjC 对象的字面空值,对应 id 类型的对象,或者使用 @interface 声明的 ObjC 对象. 例如: NSString *someString = nil; NSUR ...

随机推荐

  1. Nagios监控平台搭建及配置文件详解

    Nagios是一款开源的免费网络监视工具,能有效监控Windows.Linux和Unix的主机状态,交换机路由器等网络设置,打印机等.在系统或服务状态异常时发出邮件或短信报警第一时间通知网站运维人员, ...

  2. Hdp 4 window MR 注意事项

      1,本机未安装HDP, 在代码中加一个环境变量,跳过检查. Environment.SetEnvironmentVariable("HADOOP_HOME", @"D ...

  3. WCF 客户端连接慢

    WCF客户端第一次连接超过1分钟,以后再连接就快了. 在 Config中加入 <basicHttpBinding> <binding name="BasicHttpBind ...

  4. (转)VS2010实用快捷键

    1,Visual Studio 2008自带的1000多个 Windows 系统使用的各种图标.光标和动画文件在Visual Studio 2008的安装目录下,/Microsoft Visual S ...

  5. SLAM到底是什么?一文带你读懂SLAM

    SLAM是Simultaneous localization and mapping缩写,意为“同步定位与建图”,主要用于解决机器人在未知环境运动时的定位与地图构建问题,为了让大家更多的了解SLAM, ...

  6. 最小生成树 & 洛谷P3366【模板】最小生成树 & 洛谷P2820 局域网

    嗯... 理解生成树的概念: 在一幅图中将所有n个点连接起来的n-1条边所形成的树. 最小生成树: 边权之和最小的生成树. 最小瓶颈生成树: 对于带权图,最大权值最小的生成树. 如何操作? 1.Pri ...

  7. url 路径的拼接

    url  路径的拼接 刚开始做项目总是被路径所困扰,不知道何时该拼接,何时不拼接,怎么拼接,如何拼接,有像地址栏拼接一样的,又在跳转页面拼接的,还有在 a 标签中 href 中拼接的 ,当时做的时候一 ...

  8. 数据库,asp总结思维导图图片

  9. 003 Android常见错误汇总

    1.installation failed with message invalid file 解决办法: <1>.点击工具栏上的Build中的Clean Project <2> ...

  10. [转] 配置文件解析利器-Config库

    [From] https://blog.csdn.net/zero__007/article/details/51493851 Typesafe的Config库,纯Java写成.零外部依赖.代码精简. ...