首页 > 其他 > 详细

CCCallFuncN误用导致引用计数循环引用

时间:2014-01-26 22:33:50      阅读:582      评论:0      收藏:0      [点我收藏+]

昨天测试“角色被遮挡部分透明显示”功能时,发现角色死亡后,其轮廓精灵不会消失。调试发现,角色在死亡时,其引用计数retain_count居然是9。这是由引用计数混乱引起的内存泄露。

加了很多日志跟踪retain_count,又通过调试,终于确定了问题,是我错误使用CCCallFuncN这个CCAction导致的。于是查看cocos2d-x2.2.1源代码了解这个类的实现原理。

CCCallFuncN是CCAction的子类,是函数回调动作。我在游戏中用这个类来实现“角色死亡后倒地4秒渐渐消失再删除精灵”功能。

PathFinder::_deadAction = CCSequence::createWithTwoActions(
    CCFadeOut::create(4.0f), 
    CCCallFuncN::create(this, callfuncN_selector(PathFinder::callbackDead)));

其中,CCCallFuncN::create的第一个参数this将作为方法PathFinder::callbackDead的参数,CCCallFuncN内部会对其retain一次。

所以,PathFinder的成员引用了PathFinder,其retain_count至少是1,因此永远不会析构,循环引用导致内存泄露。

刚发现这个错误,我愚蠢地在_deadAction创建后面加了一个this->release(),这样日志中retain_count正常了,可是忘了当PathFinder析构时析构_deadAction又会对PathFinder做release()操作,导致retain_count变为负数断言。

改成这样即可,注意runAction时也会retain调用对象,目前还没发现问题:

_deadAction = CCSequence::createWithTwoActions(
    CCFadeOut::create(4.0f),
    CCRemoveSelf::create());

对于必须要使用CCFunc的函数,建议把该函数放到其他类中。 

经验:

1.千万不能让对象持有引用了该对象的成员,特别是精灵create这种隐蔽的情况;

2.精灵create时,可能会retain传入的其他对象,当然我一般不会retain,因为有自己的内存管理规则。

3.析构函数加日志,确保确实析构。

CCCallFuncN误用导致引用计数循环引用

原文:http://www.cnblogs.com/gamteq/p/3534407.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!