quick-cocos2d-x 切换新场景
在 quick-cocos2d-x 开发中,有时需要从场景 A 切换到场景 B,并释放场景 A 加载的资源。下面详细介绍相关操作及遇到的问题。
场景 A 的创建
在场景 A 中,我们创建一个 CCNode,然后将 2 个精灵添加到这个 CCNode 中。以下是具体的代码实现:
-- 创建一个节点并添加到当前场景,设置位置为屏幕中心
local container = display.newNode():addTo(self):pos(display.cx, display.cy)
-- 创建背景精灵并添加到节点
local bg = display.newSprite(SCENE_BACK):addTo(container)
self.bg = bg
-- 设置背景精灵可触摸,并允许吞噬触摸事件
bg:setTouchEnabled(true)
bg:setTouchSwallowEnabled(true)
-- 为背景精灵添加触摸事件监听器
bg:addNodeEventListener(cc.NODE_TOUCH_EVENT, function(event) self:onTouch(event) end)
-- 创建标志标签精灵并添加到节点
self.flagLabel = display.newSprite("image/scene/starttxt.png"):addTo(container)
-- 设置标志标签精灵的位置
self.flagLabel:setPosition(0, -280)
切换到场景 B 并释放资源
当切换到场景 B 时,我们希望释放场景 A 中加载的资源,也就是 2 张图片精灵对应的资源。通常会在场景 B 的 onEnter 函数中调用以下代码来释放资源:
-- 移除未使用的精灵帧
CCSpriteFrameCache:sharedSpriteFrameCache():removeUnusedSpriteFrames()
-- 移除未使用的纹理
CCTextureCache:sharedTextureCache():removeUnusedTextures()
然而,实际情况是,当场景 A 中的两个精灵添加到 CCNode 中时,上述代码并不会释放掉这 2 个精灵的图片资源。但如果场景 A 中的两个精灵直接添加到 self 中,在场景 B 的 onEnter 函数中调用上述代码是可以释放掉资源的。
问题探讨
现在的问题是,在切换场景时,我们希望通过以下两个函数完全释放上一个场景的资源,那么这两个函数应该在哪里调用呢?
CCSpriteFrameCache:sharedSpriteFrameCache():removeUnusedSpriteFrames()
CCTextureCache:sharedTextureCache():removeUnusedTextures()
在场景 A 的 onExit() 和 onCleanup() 方法中都尝试过调用这两个函数,不管精灵是添加到 CCNode 还是 self,都无法释放掉资源。
原因分析
removeUnusedTextures 方法的作用是,当纹理的引用计数为 1 时才会将其删除。
解决方案建议
可以尝试在场景 B 的 onEnter 方法中延迟调用释放资源的方法。这样做可能会让资源的引用计数在合适的时机变为 1,从而使 removeUnusedTextures 方法能够正常释放资源。