9、Cocos2dx 3.0游戏开发找小三之工厂方法模式与对象传值

原创 2014年05月30日 18:35:19

重开发者的劳动成果,转载的时候请务必注明出处http://blog.csdn.net/haomengzhu/article/details/27704153


工厂方法模式

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

在这里,我们将它稍加推广,泛指一切生成并返回一个对象的静态函数。

一个经典的工厂方法如同这样:

Sprite* factoryMethod()
 {
Sprite* ret = new Sprite();
//在这里对 ret 对象进行必要的初始化操作
return ret;
 }

这段看起来正常的代码其实隐藏着一个问题:

工厂方法对 ret 对象的引用在函数返回时已经结束,但是它没有释放对 ret的引用,埋下了内存泄露的隐患。

但是,如果在函数返回前就执行 release(),这显然是不合适的,

因为这会触发对象的回收,再返回的对象指针就成为了错误指针。


autorelease()方法很好地解决了这个问题。

此函数结束时我们已经丧失了对 ret 的引用,为了把 ret 对象传递给接受者,需要对它进行一次 autorelease 操作,这是因为虽然我们调用了 autorelease 方法,

但是对象直到自动回收池释放之前是不会被真正释放掉的(通常 Cocos2d-x 会在每一帧之间释放一次自动回收池),调用者有足够的时间来对它进行 retain 操作以便接管 ret 对象的引用权。


因此,Cocos2d-x 的执行机制很巧妙地保证了回收池中的对象不会在使用完毕前释放。

利用autorelease()修改后的工厂方法如下:

Sprite* factoryMethod()
 {
Sprite* ret = new Sprite();
//在这里对 ret 对象进行必要的初始化操作
ret->autorelease();
return ret;
 }

调用者需要在使用完毕后谨慎地释放对象;

使用工厂方法创建对象时,虽然引用计数也为 1,但是由于对象已经被放入了回收池,

因此调用者没有对该对象的引用权,除非我们人为地调用了 retain()来获取引用权,

否则,不需要主动释放对象


关于对象传值

将一个对象赋值给某一指针作为引用的时候,为了遵循内存管理的原则,

我们需要获得新对象的引用权,释放旧对象的引用权。

此时,release()和 retain()的顺序是尤为重要的。


首先来看下面一段代码:

void SomeClass::setRef(Ref* other) {
this->object->release();
other->retain();
this->object = other;
}

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

void SomeClass::setRef(Ref* other) {
other->retain();
this->object->release();
this->object = other;
}

其他可行的解决方案也有很多:

例如使用 autorelease()方法来代替 release()方法,或在赋值前判断两个对象是否相同。

在 Google 的 Objective-C 编程规范中,推荐使用 autorelease()方法代替 release()方法。


注意,只有两种情况你才需要调用release()方法

(1)你new一个cocos2d::Ref子类的对象,例如CCSprite,CCLayer等。

(2)你得到coccos2d::Ref子类对象的指针,然后在你的代码中调用过retain方法。


郝萌主友情提示:

指针不是你想release就能release!!

4、Cocos2dx 3.0游戏开发找小三之Hello World 分析

尊重开发者的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/27107295 Hello World 分析 ...

Quick cocos2dx-Lua(V3.3R1)学习笔记(5)----让精灵动起来吧,使用序列帧动画

光有精灵太死板了,游戏里面肯定有不同的动画,难道人物走动,一张静态图就能打发对游戏质量要求越来越高的玩家么?所以我们要让精灵动起来 quick里面提供了使用序列帧动画的函数,我们直接使用就行了 现...

17、Cocos2dx 3.0游戏开发找小三之内置的常用层:三剑客LayerColor、LayerGradient、Menu

重开发者的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/30476133 为了方便游戏开发者,Cocos2d...

10、Cocos2dx 3.0游戏开发找小三之容器篇:Vector、Map、Value

重开发者的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/27704153 容器 3.0版本之前Cocos2d...

5、Cocos2dx 3.0游戏开发找小三之测试样例简介及小结

重开发者的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/27186557 测试样例简介 Coc...

19、Cocos2dx 3.0游戏开发找小三之Action:流动的水没有形状,漂流的风找不到踪迹、、、

重开发者的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/30478985 流动的水没有形状,...

16、Cocos2dx 3.0游戏开发找小三之Node:父节点、子节点、傻傻分不清楚

重开发者的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/30475395 Cocos2d-x 采用了场景、层...

1、Cocos2dx 3.0游戏开发找小三之前言篇

尊重开发者的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/20409663 前言 Cocos2d-x 是...

23、Cocos2dx 3.0游戏开发找小三之粒子系统:你那里下雪了吗?

重开发者的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/30485103 春雨惊春清谷天,夏满芒夏暑相连, ...

22、Cocos2dx 3.0游戏开发找小三之音乐与音效:假如世界上没有了音乐,你的耳朵会孤单吗?

重开发者的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/30484205 假如世界上没有了音乐,在森林里,我...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:9、Cocos2dx 3.0游戏开发找小三之工厂方法模式与对象传值
举报原因:
原因补充:

(最多只允许输入30个字)