Objective-C中release和nil的关系

(iphone/ipad)浅谈Objective-C中release和nil的关系

分类: iPhone/iPad开发技术2011-12-09 01:40 2515人阅读 评论(4) 收藏 举报

uiviewcrashnull终端

注意到经常有一个这样的问题:某指针对象先release后=nil,这里后跟个=nil有什么作用?不写行不行?

简单一点说是,release是用来释放内存,nil是将对象指针设为null,nil本身对内存没什么影响,但他处理指针,尤其是避免野指针倒是很有必要。

举一个例子:

NSString *str=[[NSString alloc] init];

当我不需要str时

执行[str release];

str 的retain值减1,但是如果当前retain值>0,却紧随其后加一句str=nil;那么这时[str retainCount]应该为0,因为[nil retainCount]==0;但这时很明显存在内存泄露。

所以一个很好的写作习惯是:

当对象的retainCount==1时,写完[str release];后接着写上str=nil;       这样,当在后面的代码再次调用str相关的方法属性,也不会报错,因为之前已经将str设置为空指针,再调用str的方法也会被认为是null,不会真正调用,更不会报错。

例如下列代码:(以下所有代码段都已经过实际操作验证)

[cpp] view plaincopy

  1. UIView *view1=[[UIView alloc] init];
  2. UIView *view2=[view1 retain];
  3. int i=[view1 retainCount];
  4. NSLog(@"i:%d",i);
  5. [view1 release];
  6. view1=nil;
  7. [view1 addSubview:view2];

整个程序运行,是不会crash的。但是存在内存泄露。

但是,现在又有另外一个问题,请看下列代码:

[cpp] view plaincopy

  1. UIView *view1=[[UIView alloc] init];
  2. UIView *view2=[view1 retain];
  3. int i=[view1 retainCount];
  4. NSLog(@"i:%d",i);
  5. [view1 release];
  6. view1=nil;
  7. [view1 addSubview:view2];
  8. i=[view1 retainCount];
  9. NSLog(@"i:%d",i);
  10. i=[view2 retainCount];
  11. NSLog(@"i:%d",i);
  12. [view2 release];
  13. i=[view2 retainCount];
  14. NSLog(@"i:%d",i);

请问终端输出的log应该是什么?

第一个i=2,没问题,因为view1 init了一次,retain了1次,retain值为2。

第二个i=0,根据上面所讲的推断,也没问题,因为之前view1=nil,空指针的retainCount值为0。

第三个i=1,也没什么问题,因为view2是一个被赋了值的新指针,它不同于指针view1,二者是2个独立的指针,而且,view2还被赋了值分配了内存地址。

但是,第四个i呢?i=?

答案是i=1。为什么会这样?下面是真实输出结果:

[cpp] view plaincopy

  1. 2011-12-09 01:17:07.364 ReleaseNildemo[19115:f803] i:2
  2. 2011-12-09 01:17:07.365 ReleaseNildemo[19115:f803] i:0
  3. 2011-12-09 01:17:07.366 ReleaseNildemo[19115:f803] i:1
  4. 2011-12-09 01:17:07.367 ReleaseNildemo[19115:f803] i:1

为什么会这样?按推理说,程序执行到输出这句应该crash才对,我运行了好几遍,确实没有出现。晚上在网上和其他程序员讨论这个问题,有人运行的情况是“有时候会crash,有时候不会。断点的话不会crash”,最后大家讨论的话题开始变成“系统是先输出还是先回收?”,更有甚者,有人输出了一下内存地址,发现是view2 release前后输出的是同一个内存地址,说明,这个东西内存虽然释放了,但是系统还没来得及回收。

有时候crash,原因是你向一块未申请的内存发送了一条消息,最终成了系统回收速度问题了,所以,个人认为,以后碰到类似这种问题,干脆手动init,release,至少这样能很快释放,更便于清楚当前对象的内存情况。

以上是我对release nil操作的一些理解,欢迎更多人加入讨论

时间: 2024-12-20 19:46:59

Objective-C中release和nil的关系的相关文章

Objective-C 中 NULL、nil、Nil、NSNull 的定义及不同

来源:XcodeMen(康祖彬) 链接:http://www.jianshu.com/p/5d7033b15052 本文由我们团队的 康祖彬 童鞋撰写,这是他的个人主页:https://kangzubin.cn. 理解"不存在"的概念不仅仅是一个哲学的问题,也是一个实际的问题.我们是有形宇宙的居民,而原因在于逻辑宇宙的存在不确定性.作为一个逻辑系统的物理体现,计算机面临一个棘手的问题,就是如何用"存在"表达"不存在".–摘自 NSHipster

UIActionSheet关闭动画过程中调用delegate = nil 导致的内存泄露

UIActionSheet在动画期间(ActionSheet button点击之后,到didDismissWithButtonIndex调用完成之前)设置delegate为空会导致delegate无法释放. 先来看个例子: 例子中创建一个UIActionSheet,并在按钮点击之后0.1秒(关闭动画结束前)设置delegate = nil. #import "LIViewController.h" @class UIActionSheetDelegateImpl; static UIA

objective C中继承、协议、分类和多态的实现

第一.objective C中继承的实现 在oc中只有实例变量会有权限控制,实例方法和类方法是没有权限控制的,这点与c++不同,OC默认的是protected,并且在声明权限控制时,没有分号 在OC中可以像C++一样用指针运算法来访问实例变量 Rectangle.h 文件代码: #import <Foundation/Foundation.h> @interface Rectangle : NSObject { int _width; int _height; } @property (non

[2]工欲善其事必先利其器-------UML中的几种常见关系(二)

目录 1.UML类图中几种常见的关系 经过(一)中介绍,我选择的是StarUML作为UML的学习工具,个人喜好,至少在功能上能够满足我现在的需求, 在介绍StarUML的使用之前首先介绍下UML中几种常见的关系: UML类图中常见的关系按照关系的强弱可分为:泛化 ,实现 ,组合, 聚合 , 依赖这几种 1.泛化关系:是一种继承关系,也就是XX is a kind of XX 描述. 2.实现关系:是一种类与接口的关系. 3. 组合关系:是一种强关联,属于一种整体与部分的关系,但是部分不能离开整体

linux中权限和命令的关系。

我们知道权限对於使用者帐号来说是非常重要的,因为他可以限制使用者能不能读取/创建/删除/修改文件或目录. 一.让使用者能进入某目录成为『可工作目录』的基本权限为何: 可使用的命令:例如 cd 等变换工作目录的命令: 目录所需权限:使用者对这个目录至少需要具有 x 的权限 额外需求:如果使用者想要在这个目录内利用 ls 查阅档名,则使用者对此目录还需要 r 的权限. 二.使用者在某个目录内读取一个文件的基本权限为何? 可使用的命令:例如本章谈到的 cat, more, less等等 目录所需权限:

Makefile中头文件在依赖关系中作用

摘于:http://bbs.csdn.net/topics/120024677 (1)在makefile的依赖关系中用不用体现.h头文件?(2)如果在依赖关系中要体现.h头文件,应该体现到什么层次?==============================(1)在makefile的依赖关系中用不用体现.h头文件?============================== 下面是我的一些认识: 头文件中定义的是接口(函数接口,文件外全局变量和宏定义),它的作用是向调用文件封装函数的实现过程.在

转iOS中delegate、protocol的关系

iOS中delegate.protocol的关系 分类: iOS Development2014-02-12 10:47 277人阅读 评论(0) 收藏 举报 delegateiosprocotolcategoryobject-c 刚开始接触iOS,对delegate.protocol这两个概念比较模糊.参考了一些资料,记录下来体会. 1.protocol protocol和interface的概念类似,是object-c语法的一部分.protocol就是一系列不属于任何类的方法的列表.其中声明

理清Linux中的各种用户ID关系

在Eclipse中,出现"Access Restriction: The Type BASE64Encoder Is Not Accessible Due To Restriction"错误. 解决方法: 点击Window-->Preferences-->Java-->Compiler-->Errors/Warns,设置Deprecated And Restricted API 参数值. 问题解决. 理清Linux中的各种用户ID关系,布布扣,bubuko.co

objective C中的字符串(三)

holydancer原创,如需转载,请在显要位置注明: 转自holydancer的CSDN专栏,原文地址:http://blog.csdn.net/holydancer/article/details/7343561 objective C中的字符串操作 在OC中创建字符串时,一般不使用C的方法,因为C将字符串作为字符数组,所以在操作时会有很多不方便的地方,在Cocoa中NSString集成的一些方法,可以很方便的操作字符串,下面举几个例子: 1.创建: 直接利用等号赋值 NSString *