当一个所有者(owner,其本身可以是任何一个Objective-C对象)做了以下某个动作时,它拥有对一个对象的所有权(ownership):

1. 创建一个对象。包括使用任何名称中包含“alloc”、“new”、或者“copy”的方法。

2. 保留(retain)一个对象。

一个对象可以有多个所有者,一个所有者也可以拥有多个对象。

相应的,引用计数增减的基本规则是:

1.当所有者创建一个对象时,该对象的引用计数为1。

2.当所有者保留它时,该对象的引用计数加1。

3.当所有者释放(release)它时,该对象的引用计数减1。

与此相关的,当一个所有者对于一个对象的引用计数的增减总计为0时,它放弃了对这个对象的所有权。

现在我们可以从两个不同的角度来看Objective-C的内存管理问题。从对象所有权的角度来看,当一个对象有着至少一个所有者(owner)的时候,它依然存在;当它没有任何所有者的时候,它会被释放掉。从引用计数的角度看,一个对象存在时,其引用计数大于零;当一个对象的引用计数为零时,它会调用dealloc方法并释放掉。这两个角度的关系是:在所有权的背后起作用的机制是引用计数机制;我们通过引用计数的增减来理解所有权的概念;但是你只应当使用所有权的概念来管理内存,因为如果你试图直接获取对象的引用计数,那么得到的数将让你感到匪夷所思——系统的一些框架会“偷偷”增减对象的引用计数。

回顾一下,内存管理的目标是:

当一个对象的某个所有者依然需要使用它时,保证这个对象的存在;当一个对象的所有所有者都不再需要它时,保证这个对象被销毁。因此只要任何一个所有者在使用完一个对象之后释放掉它,那么以上内存管理的目标就可以实现。

我们可以得出任何一个所有者(记住,所有者本身也只是一个对象)所应当遵守的基本步骤:

拥有一个对象 -> 使用一个对象 -> 放弃对象的所有权。

从引用计数的角度来看就是:

还需要这个对象时,保持对其增减为正;不再需要这个对象时,保持对其增减为0。

下图很好地诠释了这些基本规则:所有者1和所有者2单独地执行了拥有对象、使用对象、放弃对象所有权的步骤;当所有者1不再需要该对象时及时放弃了所有权,但此时所有者2依然拥有该对象,因此该对象依然存在,所有者2可以继续使用它;当所有者2也不再需要该对象时,也放弃掉所有权,这时对象以不再有任何所有者(相应的引用计数也变为0),因此立刻被销毁掉。

数计数的基本规则

需要注意的是,所有者2只是复制了该对象的指针,并没有使用copy方法,因此复制指针这个操作本身并不增加对象的引用计数;而正因为所有者2希望能使用该对象,因此通过retain方法成为它的所有者,也保证了所有者1放弃该对象时,对象不被销毁。

===========附上评论==========

1 | Hui

February 13th, 2011 at 10:18 pm

你画的这个图不对吧,右边这块owner应该先retain然后再让obj1指向这个对象吧。而且如果如果obj1不是nil, 应该先把原先的对象release掉吧。我也刚看到这里,无意中看到了你的Blog。

2 | 老召

February 16th, 2011 at 8:41 am

兄弟,看你技术不错,有兴趣加入我们吗?

我们是一家在上海的技术创业企业,目前主要做iphone/ipad/android上的游戏以及交互式展示应用开发(如3D动态电子出版物插页,移动AR增强现实应用)…… 具体的你可以去我们网站上看看。另外http://app.zealion.com是我们一些项目的sample展示。

自由、激情是我们的风格,有兴趣的话可以保持联系,兼职,全职,乃至参股共同创业,我们都不排斥。

3 | 雨雪霏霏

March 13th, 2011 at 5:29 am

@Hui: 感谢你的评论。这里为了介绍引用计数的增减,就没有涉及到obj1原先值的处理。 你说的是正确的,应当release掉原先的对象,但是在release之前还要做比较。对于所有者2来说,应当做: if (obj1 != obj) { [obj1 release]; obj1 = [obj retain]; }

4 | Xie Wei

May 22nd, 2011 at 2:33 am

原来是自己画的图啊,厉害厉害!

5 | cwang

July 2nd, 2011 at 7:18 am

是不是可以用autorelease延后释放,就不用比较了(比如在setter函数里面)

将下述代码

if (obj1 != obj) { [obj1 release]; obj1 = [obj retain]; }

改为

[obj1 autorelease]; [obj1 = [obj retain];

也是可以的吧?

6 | 雨雪霏霏

July 11th, 2011 at 2:57 am

cwang:感谢回帖!是的,使用autorelease会更简单明了。

7 | 非藉秋风

August 26th, 2011 at 4:51 am

看到《Objective-C基础教程》上的处理方法也挺好: [obj retain]; [obj1 release]; obj1 = obj; 苹果建议在iPhone开发中尽量不用autorelease。

iOS内存管理系列之一:对象所有权与引用计数的更多相关文章

  1. iOS内存管理机制解析之MRC手动引用计数机制

    前言: iOS的内存管理机制ARC和MRC是程序猿參加面试基本必问的问题,也是考察一个iOS基本功是 否扎实的关键,这样深入理解内存管理机制的重要性就不言而喻了. iOS内存管理机制发展史 iOS 5 ...

  2. iOS 非ARC基本内存管理系列 2-多对象内存管理(1)

    单个对象的内存管理非常简单无非就是alloc对应release,retain对应release.但是如果涉及到很多对象,而且对象与对象有联系的时候该怎么去管理对象的内存呢. 比如同样一本书有好3个人购 ...

  3. iOS 非ARC基本内存管理系列 2-多对象内存管理(3) 利用@property来自动管理内存

    iOS 基本内存管理-多对象内存管理(2)中可以看到涉及到对象的引用都要手动管理内存:每个对象都需要写如下代码 // 1.对要传入的"新车"对象car和目前Person类对象所拥有 ...

  4. iOS 非ARC基本内存管理系列 2-多对象内存管理(2)

    /* 多对象内存管理: 以人拥有车为例涉及到@property底层set方法管理内存的实现 注意:人在换车的时候要进行当前传入的车和人所拥有的车进行判断 */ /******************* ...

  5. iOS内存管理系列之二:自动释放与便捷方法

    有时候一个所有者创建一个对象后,会立刻将该对象的指针传递给其它所有者.这时,这个创建者不希望再拥有这个对象,但如果立刻给它发送一个release消息会导致这个对象被立刻释放掉——这样其它所有者还没有来 ...

  6. python-面试常用 --变量、内存管理(小整数池,引用计数)

    执行Python程序的两种方法 第一种:交互式(jupyter就是对这种进行了封装) 优点:直接给出结果 缺点:无法保存 第二种:命令行式,通过Python解释器输入文本(pycharm对这种进行了封 ...

  7. 【Bugly干货分享】iOS内存管理:从MRC到ARC实践

    Bugly 技术干货系列内容主要涉及移动开发方向,是由Bugly邀请腾讯内部各位技术大咖,通过日常工作经验的总结以及感悟撰写而成,内容均属原创,转载请标明出处. 对于iOS程序员来说,内存管理是入门的 ...

  8. iOS内存管理(objective-c)

    移动app开发中,由于移动设备内存的限制,内存管理是一个非常重要的话题.objective-c的内存管理,不仅是面试当中老生常谈的一个必问话题,也是日常项目开发中,特别需要重视的环节.对于笔者这种以j ...

  9. iOS 内存管理(一)之基础知识介绍

    1,什么是引用计数 所有OC对象都有一个计数器,叫做引用计数,引用计数就是目前有几个对象在使用该对象(持有该对象的引用): 2,什么是对象所有权 A对象拥有B对象的引用,A对象拥有B对象的所有权: 3 ...

随机推荐

  1. uva 167 - The Sultan's Successors(典型的八皇后问题)

    这道题是典型的八皇后问题,刘汝佳书上有具体的解说. 代码的实现例如以下: #include <stdio.h> #include <string.h> #include < ...

  2. oracle2

    为什么选择oracle--性能优越 概述:目前主流数据库包括 微软: sql server和access 瑞典MySql: AB公司mysql ibm公司: db2(处理海量) 美国Sybase公司: ...

  3. Hack工具

    黑客工具一般是由黑客或者恶意程序安装到您计算机中,用来盗窃信息.引起系统故障和完全控制电脑的恶意软件程序.同时也指黑客进行黑客任务时使用的工具.著名的有nmap,流光等等. 目录 1 种类 2 恶意程 ...

  4. 打开PPT 提示安装,非要取消才能显示PPT

    自从安装VS2008后,一打开ppt文件,就开始了配置VS2008的过程. 配置完了,下回也还提示安装. 解决方案: PowerPoint选项->加载项->Chinese Translat ...

  5. Android 上使用 iconfont 的一种便捷方案

    最近在学习 AIOSO(Alibaba Internal Open Source Organization,即阿里巴巴内部开源组织) 的一个子项目MMCherryUI,这是一个流式布局,可以在运行时做 ...

  6. Struts工作流程

    Java Web 都是使用线程来处理用户的请求(request)的,一次请求对应一个处理线程.Struts 2会为每个处理线程分配一个Action对象, 将提交的参数注射到Action属性中,并调用A ...

  7. GUI编程笔记(java)02:java.awt和java.swing包的区别

    1. java.awt和java.swing两者的概述 java.awt:(java的标准包)             Abstract Window ToolKit (抽象窗口工具包),需要调用本地 ...

  8. hao123 百度品专 按品类 计算 下单数量 商品数量 下单金额?

    SELECT * FROM t_tag_source WHERE   s_name='hao123'; +--------+----------+---------+--------+-------- ...

  9. 动态添加JS文件到页面

    /*** ** 功能: 加载外部JS文件,加载完成后执行回调函数callback ***/ var utools = { config: { id: "", url: " ...

  10. gulp 前端自动化工具

    一开篇 在前端开发的过程中,我们经常会碰到压缩.合并.图片script 等,于是就有了gulp 前端自动化构建工具,它能帮你在前端开发中,节省时间. 1,安装 node.js 因为gulp 构建工具是 ...