1.工厂方法

工厂方法是程序设计中一个经典的设计模式,指的是基类中只定义创建对象的接口,将实际的实现推迟到子类中。

CCObject* factoryMethod() {

CCObject* ret = new CCObject();

//这里对ret对象进行必要的初始化操作

ret->autoRelease();

return ret;

}

使用工厂方法创建对象时,虽然引用计数也为1,但是由于对象已经被放入了回收池,因此调用者没有对该对象的引用权,除非我们人为地调用了retain()来获取引用权,否则,不需要主动释放对象。

2.关于对象传值

将一个对象赋值给某一指针作为引用的时候,为了遵循内存管理的原则,我们需要获得新对象的引用权,释放旧对象的引用权。此时,release()和retain()的顺序是尤为重要的。

void SomeClass::setObject(CCObject* other) {

this->object->release();

other->retain();

this->object = other;

}

这里存在的隐患是,当other和object实际上指向同一个对象时,第一个release()可能会触发该对象的回收,这显然不是我们想看到的局面,所以应该先执行retain()来保证other对象有效,然后再释放旧对象:

void SomeClass::setobject(CCObject* other) {

other->retain();

this->object->release();

this->object = other;

}

其他可行的解决方案也有很多,例如使用autorelease()方法来代替release()方法,或在赋值前判断两个对象是否相同。在Google的Objective-C编程规范中,推荐使用autorelease()方法代替release()方法。

3.关于release()和autorelease()

上面的两个例子实际上提出了一个问题:在使用autorelease()可以达到与release()同样的效果,甚至还能避免release()的许多隐患的情况下,是不是应该完全用autorelease()代替release()呢?

实际上,autorelease()并不是毫无代价的,其背后的垃圾池机制同样需要占用内存和CPU资源,每次执行autorelease()的过程,实际上对应的是执行成对的retain()和release(),以及一次成对的容器存取,还包括其他的逻辑判断。过多不必要的autorelease()将导致垃圾池臃肿膨胀,在存在大量内存操作的程序中会尤为严重地挤占本来就紧张的系统资源。

此外,autorelease()只有在自动释放池被释放时才会进行一次释放操作,如果对象释放的次数超过了应有的次数,则这个错误在调用autorelease()时并不会被发现,只有当自动释放池被释放时(通常也就是游戏的每一帧结束时),游戏才会崩溃。在这种情况下,定位错误就变得十分困难了。

因此,我们建议在开发过程中应该避免滥用autorelease(),只在工厂方法等不得不用的情况下使用,尽量以release()来释放对象引用。

内存管理之二——Cocos2d-x学习历程(六)的更多相关文章

  1. Linux内存管理(二)

    Linux内存管理之二:Linux在X86上的虚拟内存管理 本文档来自网络,并稍有改动. 前言 Linux支持很多硬件运行平台,常用的有:Intel X86,Alpha,Sparc等.对于不能够通用的 ...

  2. 垃圾回收GC:.Net自己主动内存管理 上(二)内存算法

    垃圾回收GC:.Net自己主动内存管理 上(二)内存算法 垃圾回收GC:.Net自己主动内存管理 上(一)内存分配 垃圾回收GC:.Net自己主动内存管理 上(二)内存算法 垃圾回收GC:.Net自己 ...

  3. DPDK内存管理-----(二)rte_mempool内存管理

    DPDK以两种方式对外提供内存管理方法,一个是rte_mempool,主要用于网卡数据包的收发:一个是rte_malloc,主要为应用程序提供内存使用接口.本文讨论rte_mempool.rte_me ...

  4. Cocos2d-x内存管理研究<二>

    http://hi.baidu.com/tzkt623/item/46a26805adf7e938a3332a04   上一篇我们讲了内核是如何将指针加入管理类进行管理.这次我将分析一下内核是如何自动 ...

  5. linux内核--内存管理(二)

    一.进程与内存     所有进程(执行的程序)都必须占用一定数量的内存,它或是用来存放从磁盘载入的程序代码,或是存放取自用户输入的数据等等.不过进程对这些内存的管理方式因内存用途不一而不尽相同,有些内 ...

  6. qemu对虚拟机的内存管理(二)

    上篇文章主要分析了qemu中对虚拟机内存管理的关键数据结构及他们之间的联系,这篇文章则主要分析在地址空间发生变化时,如何将其更新至KVM中,保持用户空间与内核空间的同步. 这一系列操作与之前说的Add ...

  7. python的内存管理与垃圾回收机制学习

    一.python内存申请: 1.python的内存管理分为六层:最底的两层有OS控制.第三层是调用C的malloc和free等进行内存控制.第四层第五层是python的内存池.最上层使我们接触的直接对 ...

  8. Redis内存管理(二)

    上一遍详细的写明了Redis为内存管理所做的初始化工作,这篇文章写具体的函数实现. 1.zmalloc_size,返回内存池大小函数,因为库不同,所以这个函数在内部有很多的宏定义,通过具体使用的库来确 ...

  9. Android 内存管理(二)

    很多开发者都是从j2me或j2ee上过来的,对于内存的使用和理解并不是很到位,Android开发网本次给大家一些架构上的指导,防止出现豆腐渣工 程的出现.Android作为以Java语言为主的智能平台 ...

随机推荐

  1. Windows XPE 安装

    to liuxiyao: 出现这样的问题我推断是由于系统有一些必须的dll类库没有被build进系统中,你在构建时多加入一些系统组件试试.(我想通过评论发可是发了5.6遍CSDN没反应,就写到这里吧, ...

  2. 水平居中的两种方法margin text-align

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  3. C# 7 函数 青歌赛打分 天气预报

    函数: 数据类型--变量常量--运算符表达式--语句(顺序,分支,循环)--数组--函数 程序里的函数:能完成一个相对独立功的代码块. 数学里的函数:高度抽象. 函数四要素:函数名,输入,输出,加工 ...

  4. MapReduce详解

    1.mapreduce之shuffle http://blog.csdn.net/thomas0yang/article/details/8562910 2.彻底了解mapreduce核心Shuffl ...

  5. 多个DLL合并,DLL合并到EXE

    1:) 下载 http://download.microsoft.com/download/1/3/4/1347C99E-9DFB-4252-8F6D-A3129A069F79/ILMerge.msi ...

  6. 鼠标聚焦到Text输入框时,按回车键刷新页面原因及解决方法

    前提 一个form中只有一个输入框,当输入框获取焦点后,点击回车,导致整个页面都刷新,问题解决办法. 1.处理form  在form中添加事件 <form onsubmit="retu ...

  7. Python入门之中文乱码

    python入门编码: Python 文件中如果未指定编码,有中文代码时候,在执行过程会出现报错: File "test.py", line 2 SyntaxError: Non- ...

  8. js/jquery获取当前页面URL地址并判断URL字符串中是否包含某个具体值

    js/jquery获取当前页面URL地址并判断URL字符串中是否包含某个具体值本文介绍jquery/js获取当前页面url地址的方法,在jquery与js中获取当前页面url方法是一样的,因为jque ...

  9. Node.js包管理器:

    Node.js包管理器: 当我们要把某个包作为工程运行的一部分时,通过本地模式获取,如果要在命令行下使用,则使用全局模式安装 使用全局模式安装的包并不能直接在JavaScript文件中用require ...

  10. 修改默认的undo_retention参数设置

    昨天,一个朋友的数据库数据被误操作删除掉了,请求我帮忙进行恢复. 数据库版本是Oracle10g Release 2的,我首先想到的是使用Flashback Query进行闪回恢复,不幸的是ORA-0 ...