Quick cocos2dx 2.2.5 里面 ui.newSprite ui.newAnimation ui.newFrames 创建的对象该怎么释放呢?

quick cocos2dx 2.2.5 里面 ui.newSprite ui.newAnimation ui.newFrames 创建的对象该怎么释放呢?

不然,造成了内存泄露该怎么办?

看samples和源码都弄不明白

不能管杀不管埋吧

从场景上移除后会自动释放的

从场景上移除

单独对创建的sprite做removeChild吗?

还是只需要把导入了CocoStudio的uiLayer removeFromParentAndCleanup?

我参考了这个帖子的说明http://www.cocoachina.com/bbs/read.php?tid=200303

但是仍然不得要领,因为我的界面上既有CocoStudio的的JSON UI,又在这些UI下通过addNode挂了quick的ui.newSprite 和 ui.newAnimation等子对象的

不知道在onExit的时候 对CocoStudio的JSON UI 和addNode挂载的子对象要分别做什么处理?

另外:我把这些addNode的子对象放入Lua的weak key Table,切换Scene之后,观察这些addNode的quick ui对象,确实存在内存泄露

测试环境quick 2.2.5 cocoStudio1.6.0.0 Win32 player

贴上我目前的onExit调用的内存释放代码

全局函数
function recycle()
–内存清理开始
local c2 = collectgarbage(“count”)
collectgarbage(“collect”)
–print(“time”…tostring(os.time())…"=============MemEnd>>>>22222222>>>>>>>>>>>>>", c2)
print("=============MemEnd>>>>22222222>>>>>>>>>>>>>", c2)
end

function purge(scene)
– 清理场景管理(所有读取的场景都会被清理掉)
SceneReader:sharedSceneReader():purge()
– 清理GUI管理类(这个不要放到最后清理)
GUIReader:purge()

-- 清理动作(这里指Action动作,不是动作编辑器的动作。)  
ActionManager:purge()

CCArmatureDataManager:purge()

-- 释放掉不用的纹理
display.removeUnusedSpriteFrames() 
-- CCSpriteFrameCache:sharedSpriteFrameCache():removeUnusedSpriteFrames()
-- CCTextureCache:sharedTextureCache():removeUnusedTextures()

-- 释放动作
-- if scene then
--     scene:getActionManager():removeAllActions()
-- end
--ActionManager:shareManager():purge()

recycle()
recycle()
recycle()

CCTextureCache:sharedTextureCache():dumpCachedTextureInfo()

end

场景onExit

function BattleScene:onExit()
– 禁用帧事件
self:unscheduleUpdate()

self._uiLayer:removeAllChildrenWithCleanup(false)
self._uiLayer:removeFromParentAndCleanup(true)
self._uiLayer = nil

purge()
dumpWeakTable()

end

newSprite就是个封装,实际上调用的就是Sprite:create(),对应到C++就是创建了一个Sprite对象。你应该知道在调用create时是设置了autorelease的,所以只要引用计数为0,就会被释放掉。其他newAnimation和newFrames等都类似。所以可以肯定的说,只要它们已经从场景中被移除,并且不被其他任何对象持有,肯定会自动释放。
如果你确实还有内存泄露问题,建议你检查ccs控件类是否完成释放了,又或者有其他逻辑问题造成对象仍然被引用。怀疑Sprite等自己不会自动释放,方向是错误的。

我还没有怀疑到底层,对于底层实现我也大概看了看代码

”只要它们已经从场景中被移除,并且不被其他任何对象持有,肯定会自动释放“

这个我也认可

我现在的关注问题是在应用层,即通过CocoStudio json UI以及quick newSprite等创建的对象 如何简单有效地卸载释放资源(暂不考虑其他游戏逻辑对这些对象的引用,只考虑简单的UI显示)

如果按照UI层级逐级逐级实现卸载代码,固然没有问题,但是开发调测效率不高

参考CocoStudio的C++例子 ,希望
self._uiLayer:removeFromParentAndCleanup(true)
self._uiLayer = nil

purge()

即可完成卸载,其中 _uiLayer 是JSON UI的parent,是场景类的 child

但是我今日通过测试发现,如果通过addNode挂载了quick ui.newSprite

卸载代码应该这样写(测试通过)

function BattleScene:onExit()
– 禁用帧事件
self:unscheduleUpdate()

local roadlayer, soldierLayer
roadlayer = self._uiLayer:getWidgetByName("RoadLayer1")
soldierLayer = roadlayer:getChildByName("SoldierLayer")
soldierLayer:removeAllNodes()

self._uiLayer:removeAllChildrenWithCleanup(false)
self._uiLayer:removeFromParentAndCleanup(true)
self._uiLayer = nil

purge()
dumpWeakTable()

end

需要对 addNode添加的对象 做一次手动释放,而addWidget的添加对象则只需要将根uiLayer卸载即可

也就是说 Node对象需要手动释放,而Widget对象只需要将根卸载即可

但是这只是我的推测,在此求证

希望版主能为我解惑

我没有研究过CocoStudio的实现,按我的理解,它自己的UI场景里应该默认载入自己的控件,在此基础上,其自动清理是不会有问题的。但在使用其他的Node时,可以看到ccs使用的是addNode而不是更常见的addChild,那么可以推断它使用了自己的方式来处理其他Node的挂载,因此必须自己调用removeAllNodes()也是可能的,这个只能向ccs的开发团队确认了。
需要指出的是,你之所以会出现当前这一困惑,显然是在使用ccs时混用了其他非ccs的控件,这种方式其实不值得推荐。对象的释放还只是小问题,如果涉及到消息的传递,不同消息机制混用的结果,对它们的处理恐怕会成为一场恶梦。
如果你确实希望混用两类控件,建议你看一下sample/ccsloader,按里面的方式将ccs的布局转换成纯lua控件使用,或许是更好的处理方式。

好的,谢谢提醒,我这就去学习ccsloader去

混用也是没有办法的事情,UI编辑目前看来CocoStudio还是不错的,quick的Lua封装也非常好用

另外,问一下,现在cssloader可商用了吧?quick 2.2.5会一直支持不?

会一直支持的

不用CocoStudio的路过