【已解决】关于对象池的管理!

当前使用的Creator版本1.9.2 mac版本。

使用NodePool一开始 加载好 Prefab 创建了200个node放进对象池,好吧,这不是重点。

重点是就在当前场景,我一直游戏,一直玩到后面好久,对象池中 Node 节点中的SpriteFrame丢失,我确认都已经赋值成功了,但就是不显示,一个个空白,而且游戏继续进行,从丢一二个开始,越到后面丢失的数量越严重。

切换场景我已经clear了对象池重新初始化,一样会出现,先不考虑切换场景了,现在问题是没切换场景就以及有问题了。

最最重点来了:不用对象池,一切安好,我只能怀疑是 NodePool 的bug了。

代码就不发了,并没有特殊操作。

@jare @panda

3赞

还是发一下代码吧,node pool 这么简单的东西再出bug那等于打官方的脸啊

如果只发NodePool 那部分的代码,真的没什么发的,我就把我prefab创建出来的node,初始化先put 100个,用的适合get,切场景之前clear(其实和切场景没关系,这里clear不用调用到后面就已经会产生bug了)。

如果这个代码不够,那我只能发项目代码,这个不适合发。而且就算我发了,你得耐心的玩5分钟以上,只有到后面才会出这个bug。

游戏中,界面滚动的时候,就把之前的回收掉,后面新产生的从 NodePool 中取。

我现在已经不用对象池了,把代码里

对象池 get 的地方,换成 cc.instantiate(prefab) ,对象池 put 的地方,换成 prefabNode.destroy()

一切美极了。

明天周一准备上线了,效率是要低一点,但是至少游戏没有bug。

NodePool 没有对节点做任何操作的,只能说是节点使用过程中对节点状态控制有问题,或者是不小心销毁了节点,这是绝对不行的

我也遇到了这种情况,即使自己写了一个node缓存,重复使用带有sprite的node也还是会出现这种情况。请问creator是否有自动释放spriteframe的处理?(我取消了scene的自动释放选项,不知道有没有影响,出现问题的时候没有切换scene的操作)这些代码之前在2dx运行是没有问题的,移植到Creator里就出了问题。

Hi ,您好panda,我几乎可以确信我没有不小心销毁节点,我只是调用了node.removeFromParent(false)方法,后来查看NodePool的文档说put,会自动调用removeFromParent()方法,我就移除了我自己的调用,可是还是到最后spriteframe丢失。

我尝试过自己写个数组模仿作为对象池来保存这些重复使用的结点,依然会出现类似 NodePool 的问题,spriteframe丢失。

初始化出问题了 或者把其他的节点也放到对象池了 检查一下你的初始化init函数和回收节点的函数

我做捕鱼,初始化放对象池了几百个,没有出现你说的现象

是否用cc.loader.release释放过资源

初始化的方法:

initialize(unitPrefab){
        this._unitPrefab = unitPrefab;
        this._unitNodePool = new cc.NodePool();

        for (let i = 0; i < 200; ++i) {
            let unit = cc.instantiate(this._unitPrefab);
            this._unitNodePool.put(unit);
        }
    }

回收的方法:

recycle(/**@type {cc.Node}*/unitNode) {
        let unitView = unitNode.getComponent(UnitView);

        this._unitNodePool.put(unitNode);
    }

有什么问题?

没有调用过此方法。

那就真的很奇怪了啊。我不用对象池一点问题都没有。

可以提供个demo吗?我们这边分析一下,对象池用的游戏很多,有出现问题的,都可以解决的。

非常感谢官方团队的回复。

如果要demo的话,请给我一点点时间,这个是公司项目。我只能把部分功能抽出来,写一个demo还原这个问题。

请给我一天左右的时间。:slightly_smiling:

没问题。demo上传后,麻烦@我一下,不然没有通知。

我是用数组管理的,没有出现楼主的问题啊。。

今天花了半天时间,把这个demo写完了。后面就麻烦您花费宝贵时间,帮我check一下拉!你会发现我代码里没有任何的特殊操作。

@huanxinyin

补充一点:
一直用鼠标点击,点到350层的时候,问题开始出现,越往后丢失越明显严重。(正常情况是每一行都有楼梯,你可以打断点看数据)

UnitView.js文件中下面这个位置:(使用对象池,和不使用对象池的情况)

recycle(/**@type {cc.Node}*/unitNode) {
        /** 使用对象池回收结点 Unit Node. */
        let unitView = unitNode.getComponent(UnitView);//无用

        this._unitNodePool.put(unitNode);


        /** 不使用对象池回收,直接销毁 Unit Node. */
        // unitNode.destroy();
    }

问题非常明显,我真诚的期待您的回复。谢谢。

我再发两张我用不用对象池的正常截图和使用对象池纹理丢失的异常截图:

也请 @panda 有空继续帮我check一下这个问题,上面这个demo的工程源码已放出。代码几乎是已经简化到非常的很简单 的地步了,但是spriteframe还是丢失了。。。

:grin: 你的配置文件错了,创建了几个空节点把pool弄脏了。