内存管理之二——Cocos2d-x学习历程(六)
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学习历程(六)的更多相关文章
- Linux内存管理(二)
Linux内存管理之二:Linux在X86上的虚拟内存管理 本文档来自网络,并稍有改动. 前言 Linux支持很多硬件运行平台,常用的有:Intel X86,Alpha,Sparc等.对于不能够通用的 ...
- 垃圾回收GC:.Net自己主动内存管理 上(二)内存算法
垃圾回收GC:.Net自己主动内存管理 上(二)内存算法 垃圾回收GC:.Net自己主动内存管理 上(一)内存分配 垃圾回收GC:.Net自己主动内存管理 上(二)内存算法 垃圾回收GC:.Net自己 ...
- DPDK内存管理-----(二)rte_mempool内存管理
DPDK以两种方式对外提供内存管理方法,一个是rte_mempool,主要用于网卡数据包的收发:一个是rte_malloc,主要为应用程序提供内存使用接口.本文讨论rte_mempool.rte_me ...
- Cocos2d-x内存管理研究<二>
http://hi.baidu.com/tzkt623/item/46a26805adf7e938a3332a04 上一篇我们讲了内核是如何将指针加入管理类进行管理.这次我将分析一下内核是如何自动 ...
- linux内核--内存管理(二)
一.进程与内存 所有进程(执行的程序)都必须占用一定数量的内存,它或是用来存放从磁盘载入的程序代码,或是存放取自用户输入的数据等等.不过进程对这些内存的管理方式因内存用途不一而不尽相同,有些内 ...
- qemu对虚拟机的内存管理(二)
上篇文章主要分析了qemu中对虚拟机内存管理的关键数据结构及他们之间的联系,这篇文章则主要分析在地址空间发生变化时,如何将其更新至KVM中,保持用户空间与内核空间的同步. 这一系列操作与之前说的Add ...
- python的内存管理与垃圾回收机制学习
一.python内存申请: 1.python的内存管理分为六层:最底的两层有OS控制.第三层是调用C的malloc和free等进行内存控制.第四层第五层是python的内存池.最上层使我们接触的直接对 ...
- Redis内存管理(二)
上一遍详细的写明了Redis为内存管理所做的初始化工作,这篇文章写具体的函数实现. 1.zmalloc_size,返回内存池大小函数,因为库不同,所以这个函数在内部有很多的宏定义,通过具体使用的库来确 ...
- Android 内存管理(二)
很多开发者都是从j2me或j2ee上过来的,对于内存的使用和理解并不是很到位,Android开发网本次给大家一些架构上的指导,防止出现豆腐渣工 程的出现.Android作为以Java语言为主的智能平台 ...
随机推荐
- linux共享内存简析
共享内存是IPC的一种机制,允许两个不相关的进程共享同一块内存 //共享内存可以双向通信,但其本身没有相应机制,需要程序编写者设计,本例为单向通信(分为读端和写端). 共享内存读端: #include ...
- BZOJ 1833 ZJOI2010 count 数字计数 数位DP
题目大意:求[a,b]间全部的整数中0~9每一个数字出现了几次 令f[i]为i位数(算前导零)中每一个数出现的次数(一定是同样的,所以仅仅记录一个即可了) 有f[i]=f[i-1]*10+10^(i- ...
- Windows 应用程序结构
Windows 应用程序结构
- 移动端适配:font-size设置的思考
1. 问题的引出 如果html5要适应各种分辨率的移动设备,可以使用rem这样的尺寸单位,针对各个分辨率范围在html上设置font-size的代码: html{font-size:10px} @me ...
- mybatis中使用log4j
Mybatis默认使用有slf4j,所以必须加入下面的依赖,否则可能出现日志无法打印sql或者无法打印resultset. <dependency> <groupId>org. ...
- 用HtmlLink来改变网站的主题
#region Theme // 注册样式(将主题样式至于通用样式后面) HtmlLink themeCss = new HtmlLink(); themeCss.Href = GetThemeUrl ...
- JS 利用CNZZ进行站长统计
利用CNZZ对网站进行站长统计 前端页面只需要在body中添加如下代码即可: <script type="text/javascript">var cnzz_proto ...
- Android开发 学习笔记——HelloWorld
Day01 1.java开发过程———————————————不建议先用ECLIPSE写代码,因为它的函数式自动生成的,不利于找寻编程手感打开记事本写完程序后,修改扩展名为.java然后在DOS控制台 ...
- document_createElement
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- IOS开发 统计XCODE 代码行数
如果要统计ios开发代码,包括头文件的,终端命令进入项目目录下,命令如下 find . -name "*.m" -or -name "*.h" -or -nam ...