转载请注明出处:http://www.cnblogs.com/shamoyuu/p/OC_CG.html

最近学习了Objective-C语言(以下简称OC),其他的都还好,唯有它的内存管理让我不知所措。因为OC跟我熟悉的Java、C#、js语言不同。Java,C#和js都是自动的垃圾回收,资源都是托管给虚拟机或者引擎,让他们定期查找不再使用的对象然后销毁。而OC的内存管理跟C和C++一样完全手动,我们程序员需要负责一个对象从生到死的每个过程,想想都心累。如果不做内存管理,不释放对象资源,那对象就会一直在内存中,很容易就内存溢出,程序闪退。

OC的内存管理对任何继承了NSObject的对象都适用,对其他的基本数据类型无效。

在代码块运行完成后,栈空间的变量会自动回收,但是堆空间的对象是无法自动回收的,只能手动回收。在Java中,如果没有任何变量指向一个对象的时候,就会被标记回收了。

OC里每个对象都有自己的引用计数器,它是一个整数,表示对象被引用的次数。如果计数器是0,则表示没有变量引用它,就会被回收。如果计数器不为0,那它就会一直在内存中,不会被回收。
当一个对象被销毁的时候,系统会自动调用对象的dealloc方法,一般我们会重写dealloc方法,用来释放相关的资源。
如果重写了dealloc方法,那一定要调用[super dealloc],并且放在最后,因为要先销毁子对象的资源,然后让父对象去销毁,这和创建对象的过程相反。
如果一个对象引用计数器变成0,那这个对象就被释放了,它就叫做僵尸对象。
如果一个指针指向一个僵尸对象,那么这个指针就叫野指针。
访问一个僵尸对象就会报EXC_BAD_ACCESS,很常见的错误,有点类似Java里的空指针。
应该在对象释放的时候,给指针赋值nil,nil就是空指针,而调用空指针的方法是不会报错的,跟Java里完全不一样。

当使用alloc、new和copy创建一个新对象的时候,新对象的引用计数器默认是1。

跟引用计数器相关的常用方法有这3个:

  • retain:引用计数器+1,并返回对象本身
  • release:引用计数器-1,没有返回值
  • retainCount:获得当前引用计数器的值

因为多个指针可以指向同一个对象,这样会使计数器加减混乱,所以我们在写OC代码的时候有两个原则:

  1. 谁创建,谁release
  2. 谁retain,谁release

总结一下就是“谁+1,谁-1”,只有这样,对象的引用计数器都可以正确地进行操作。

在OC里面有一个autoreleasepool(自动释放池)对象,它可以接管autorelease(自动释放)的对象,在这个自动释放池销毁的时候,它里面所有的自动释放对象都会调用release方法。

@autoreleasepool //创建了自动释放池对象
{
Animal *dog = [[[Animal alloc] init] autorelease]; [dog eat];
} //销毁了自动释放池对象

这样做的好处是显而易见的,可以自动帮我们把创建的对象的引用计数器减1,如果只有一个指针指向它的话(大多数情况都是如此),就不必我们手动release来释放了。

自从ios6有了ARC以后,内存管理就不用这么复杂了^_^

【其他】Objective-C 内存管理学习总结的更多相关文章

  1. Objective C内存管理之理解autorelease------面试题

    Objective C内存管理之理解autorelease   Autorelease实际上只是把对release的调用延迟了,对于每一个Autorelease,系统只是把该Object放入了当前的A ...

  2. C++内存管理学习笔记(5)

    /****************************************************************/ /*            学习是合作和分享式的! /* Auth ...

  3. C++内存管理学习笔记(6)

    /****************************************************************/ /*            学习是合作和分享式的! /* Auth ...

  4. C++内存管理学习笔记(7)

    /****************************************************************/ /*            学习是合作和分享式的! /* Auth ...

  5. Linux内存管理学习资料

    下面是Linux内存管理学习的一些资料. 博客 mlock() and mlockall() system calls. All about Linux swap space 逆向映射的演进 Linu ...

  6. C++内存管理学习笔记(4)

    /****************************************************************/ /*            学习是合作和分享式的! /* Auth ...

  7. C++内存管理学习笔记(3)

    /****************************************************************/ /*            学习是合作和分享式的! /* Auth ...

  8. C++内存管理学习笔记(2)

    /****************************************************************/ /*            学习是合作和分享式的! /* Auth ...

  9. C++内存管理学习笔记(1)

    /****************************************************************/ /*            学习是合作和分享式的! /* Auth ...

  10. c++内存管理学习纲要

    本系列文章,主要是学习c++内存管理这一块的学习笔记. 时间:6.7-21 之下以技术内幕的开头语,带入到学习C++内存管理的技术中吧: 内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题 ...

随机推荐

  1. 图像映射<map>、<area>

    1.<map>定义图像映射,图像映射(image-map)指带有可单击区域的一幅图像. 2.<area>定义图像映射中的区域,area元素永远嵌套在map元素内部,area元素 ...

  2. spring中Bean对象的生命周期

    经过测试对于具体的一个Bean,执行的流程应该是: 1.实例化: 常见的有构造(有参.无参)实例化.静态工厂(方法是静态,通过类名.方法返回获取).实例工厂(专门有个类负责生产对象,需要在bean中配 ...

  3. 【Tomcat】Tomcat的使用

    第一章 JDK的安装 1.1  windows下安装 1.1.1  配置环境变量 安装完成后,还要进行 Java 环境的配置,才能正常使用,步骤如下: (1)在我的电脑点击右键——〉选择属性, (2) ...

  4. 700名黑客无法攻破Trillium安全防护软件 欲以网络安全险获利

    盖世汽车讯 据外媒报道,在2017 DEF CON黑客大会上,黑客们受邀入侵Car Hacking Village会场内的各类自动驾驶车辆.物联网网络安全公司--Trillium Incorporat ...

  5. 洛谷 [P1154] 奶牛分厩

    类似筛法的思想 本题实际上就是反推hash的模数, 首先想到枚举k,但显然会超时. $a mod k==b mod k <==> k|(a-b) $ 由同余的定义可以知道 所以我们的任务就 ...

  6. 洛谷 [P1403] 约数研究

    本题的思想很好,正难则反 首先如果暴力枚举每个数的约数个数,一定会超时,那么我们就从约数的角度考虑,题目中问的是1~n的约数个数和,那么我们就枚举约数,看每个约数在1~n中出现过几次. #includ ...

  7. cdcqの省选膜你赛

    cdcqの省选膜你赛 比赛当天因为在杠hnoi2016的大数据结构没有参加,今天补了一下.挺好玩的虽然不看一句话题意的话真的卡读题 此生无悔入东方,来世愿生幻想乡 2651. 新史「新幻想史 -现代史 ...

  8. SUSE-11 本地 zypper 配置

    配置本地 zypper 目的: 安装 SUSE-11 后想要再添加或删除软件组件将比较麻烦.通过配置本地 zypper 将可以从下载的软件仓库(repository)中安装软件包.   本地 zypp ...

  9. PHP将HTML的内容保存成word文档

    <?php class word { function start() { ob_start(); echo '<html xmlns:o="urn:schemas-micros ...

  10. python学习:收集ip信息

    #!/usr/bin/env python   from subprocess import Popen, PIPE   def getIfconfig():     p = Popen(['ifco ...