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

注意到经常有一个这样的问题:某指针对象先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,不会真正调用,更不会报错。

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

  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的。但是存在内存泄露。

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

  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。为什么会这样?下面是真实输出结果:

  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操作的一些理解,欢迎更多人加入讨论

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

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

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

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

    本文由我们团队的 康祖彬 童鞋撰写,这是他的个人主页:https://kangzubin.cn. 理解"不存在"的概念不仅仅是一个哲学的问题,也是一个实际的问题.我们是有形宇宙的居 ...

  3. Python类中super()和__init__()的关系

    Python类中super()和__init__()的关系 1.单继承时super()和__init__()实现的功能是类似的 class Base(object): def __init__(sel ...

  4. 转iOS中delegate、protocol的关系

    iOS中delegate.protocol的关系 分类: iOS Development2014-02-12 10:47 277人阅读 评论(0) 收藏 举报 delegateiosprocotolc ...

  5. 理解Objective C 中id

    什么是id,与void *的区别 id在Objective C中是一个类型,一个complier所认可的Objective C类型,跟void *是不一样的,比如一个 id userName, 和vo ...

  6. 浅谈Objective—C中的面向对象特性

    Objective-C世界中的面向对象程序设计 面向对象称程序设计可能是现在最常用的程序设计模式.如何开发实际的程序是存在两个派系的-- 面向对象语言--在过去的几十年中,很多的面向对象语言被发明出来 ...

  7. java中接口与多重继承的关系

    在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制.正是由于这两种机制的存在,才赋予了Java强大的 面向对象能力.abstract class和int ...

  8. C/C++中数组与指针的关系探究

    数组与指针 长期以来,在C/C++中,数组名和指向数组首元素的指针常量到底是以一种什么关系,一直困扰着很多人.很多地方,甚至是一些教科书中都在说,"数组名就是一个指向数组首元素的指针常量&q ...

  9. 计算机基础--Java中int char byte的关系

    计算机基础--Java中int char byte的关系 重要:一个汉字占用2byte,Java中用char(0-65535 Unicode16)型字符来存字(直接打印输出的话是字而非数字),当然要用 ...

随机推荐

  1. Leetcode_ Best Time to Buy and Sell Stock II

    Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...

  2. iptables 添加,删除,查看,修改

      iptables是linux系统自带的防火墙,功能强大,学习起来需要一段时间,下面是一些习iptables的时候的记录.如果iptables不熟悉的话可以用apf,是一款基于iptables的防火 ...

  3. java,C#接口与C++的虚基类

    看C#的接口感觉就像C++中继承并实现虚基类的函数方法一样,是OOP编程中表现多态的一种方式.可以参考下面的文章: http://blog.sina.com.cn/s/blog_60ff8f1b010 ...

  4. IDEA 快捷键整理

    1. IDEA内存优化  \IntelliJ IDEA 9\bin\idea.exe.vmoptions ----------------------------------------- -Xms6 ...

  5. redis 学习笔记三(队列功能)

    Redis队列功能介绍 List 常用命令: Blpop删除,并获得该列表中的第一元素,或阻塞,直到有一个可用 Brpop删除,并获得该列表中的最后一个元素,或阻塞,直到有一个可用 Brpoplpus ...

  6. Ext.window的close的问题

    以前每次都是用的hide,关闭后隐藏窗体,下一次点击再打开,这种方法在我的随笔里面有,可是现在遇到一个问题,我的窗体里面有个formpanel,formpanel每一项都有一个默认值,意思就是修改的时 ...

  7. Struts2简单例子

    Struts实现注册功能 ControlFilter.java package com.jikexueyuan.filter; import java.io.IOException; import j ...

  8. 泛型 Field 和 SetField 方法 (LINQ to DataSet)

    LINQ to DataSet 为 DataRow 类提供用于访问列值的扩展方法:Field 方法和 SetField 方法.这些方法使开发人员能够更轻松地访问列值,特别是 null 值.DataSe ...

  9. Arcgis API for Android之GPS定位

    欢迎大家增加Arcgis API for Android的QQ交流群:337469080 先说说写这篇文章的原因吧,在群内讨论的过程中,有人提到了定位的问题,刚好,自己曾经在做相关工作的时候做过相关的 ...

  10. AVL旋转树

    执行插入操作可能出现不平衡的情况,当平衡二叉树.AVL这树是一种自平衡二叉树,使二叉树又一次保持平衡.而且查找.插入和删除操作在平均和最坏情况下时间复杂度都是O(log n) AVL树的旋转一共同拥有 ...