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. C++暂时对象

    C++真正所谓的暂时对象是不可见的--不会在你的源码中出现.仅仅要你产生一个non-heap object而没有为它命名,便诞生了一个暂时对象.此等匿名对象通常发生于两种情况: 一是当隐式类型转换(i ...

  2. 分享一个用安卓手机就能引导pc安装linux系统办法

    1.首先安卓手机下载软件DriveDroid.apk http://pan.baidu.com/s/1qW4pbT6 2.下载linux镜像文件放手机存储卡存储,放到Download/images/以 ...

  3. mysql启动报错:Fatal error: Can’t open and lock privilege tables: Table ‘mysql.host’ doesn’t exist

    mysql在首次启动的时候可能会报错:Can’t open and lock privilege tables: Table ‘mysql.host’ doesn’t exist 这时候可以执行脚本 ...

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

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

  5. mysql 重启

    /etc/init.d/mysql restart /etc/init.d/mysql stop /etc/init.d/mysql start

  6. 利用sql里的xpath生成表格

    SELECT (SELECT * from Common.Common_Setup_CityData FOR XML PATH('tr'), TYPE).query('      for $item ...

  7. python基础:名称空间与作用域

    Python的变量定义后都有自己的作用域,每个作用域内都有名字空间.名称空间就是变量名称与对象的关联关系.Python中使用变量名引用对象,需要使用该变量时,就在命名空间中进行搜索,获取对应的对象.从 ...

  8. 预定义异常 - PHP手册笔记

    Exception是所有异常的基类,类摘要如下: <?php class Exception { protected string $message; // 异常消息内容 protected i ...

  9. python----面向对象:1类的定义

    1.python中定义类的格式如下: class className(baseClassName): def functionName(argslist): 2.定义一个person类:它有一个Nam ...

  10. 安卓使用spinner控件和pull解析实现全国省市县的三级联动

    实现该功能主要有两个难点: 1.XML文件的Pull解析.由于XML文件的结构较为复杂,所以解析时要注意,划分XML文件的结构,根据结构建立相应的和集合.本例中需要建立三个类和三个对象.三个类分别为, ...