代码
local sprite1 = cc.Sprite:create('a.png');
local action = cc.DelayTime:create(1);
sprite1:runAction(action);
如果这里sprite1没有用addChild加入到任何scene中,直接丢掉的话,以后就再没有机会释放这个sprite了。而且sprite对应的图像也没有被释放,造成内存泄漏。
原因分析
当对一个node进行runAction时,ActionManager会对它执行retain操作。对应的,需要到stopAction时才会进行release。
正常情况下,一般把node加入到scene中。所以要么action执行结束自行停止。要么手动使用了stopAction。要么在上一级node调用removeChild的时候进入cleanup(会调用stopAllActions)。这些情况都不会造成问题。
但如果不把这个node加入到任何scene,那就不会自动执行到stopAction,所以始终不会release了。
发现过程
项目中封装了一个Effect类,大致是创建一个sprite然后用runAction(cocos2dx::Animate)来做帧动画,并返回创建的sprite。
后来希望预加载,就直接创建Effect但没有加入到任何scene中,直接丢弃。
结果出现上述问题,导致预加载的图片不能释放。
解决方案
如果node没有加入到任何scene,并且进行了runAction,那么必须手动stopAction。
因为会进行这种操作的场合并不多,一般也无需特别注意。只要检查所有的图片都正确释放,内存一般就不是大问题了。