关于移除节点的一点提问

ccc版本号:2.2.1
最近项目有个界面用元素需要复用,就想着用对象池。但是在运用过程中发现了几个问题,没搞明白。

  • 首先贴一下代码

    onLoad () {

      //创建对象池
      this.ParityPool = new cc.NodePool();
    

    },

    OnGetParityNode() {

      let nodeItemParity = null;
      if (this.ParityPool.size()>0) {
          nodeItemParity = this.ParityPool.get();
      } else {
          nodeItemParity = cc.instantiate(this.pfItemParity);
      }
      let jsItemParity = nodeItemParity.getComponent("jsItemParity");
      jsItemParity.OnReuseView();
    
      return nodeItemParity;
    

    },

    OnPutParityNode() {

      let aryChild = this.nodeParityList.children;
      while (aryChild.length > 0 ) {
          let nodeItemParity = aryChild.shift();
          // nodeItemParity.removeFromParent();
          // nodeItemParity.parent = null;
          this.ParityPool.put(nodeItemParity);
      }
    

    },

  • 遇到的几个问题。

  1. 重复使用时,第二次使用OnGetParityNode,是从对象池中获取到的节点。执行
    this.nodeParityList.addChild(nodeItemParity);代码时会报错 如下:image

  2. 但是重复使用试如果执行的是的:
    nodeItemParity.parent = this.nodeParityList;
    是不会有上面那个重复添加的报错,但是在第二次复用的时候会不显示。
    第一个疑惑点:打印this.nodeParityList子节点个数,发现为0?就很奇怪。如下图。image
    第二个疑惑点:文档中说的对象池使用put回收时,会自动调用节点的removeFromParent()。执行后,断点查看父节点child是为空,但是在从对象池获取拿出来使用时,nodeItemParity的父节点属性还在,所以再执行addchild时,会有第一个报错吧。

  3. 既然发现是在回收时,没有移除干净就想着自己手动把父节点置空。就在回收代码中添加了:
    nodeItemParity.parent = null;
    现在来到第三个疑惑点了:是能正常显示了,但是在置空父节点的时候会有如下报错:
    image

查看了一下论坛相关的问题,感觉都没有得到官方回答和解决方案。。求解惑。 !

回收子节点从最后一位开始回收

你是说这样么。shift改成pop?

OnPutParityNode() {
    let aryChild = this.nodeParityList.children;
    while (aryChild.length > 0 ) {
        let nodeItemParity = aryChild.pop();
        // nodeItemParity.removeFromParent();
        // nodeItemParity.parent = null;
        this.ParityPool.put(nodeItemParity);
    }
},

还是一样的问题。

QQ截图20210601111014

这样试一下。

这样子是可以解决问题并且没有报错了。 但还是好奇节点使用removeFromParent后,自身的父节点属性还存在。 。 移除不彻底么

removeFromParent 里面有判断,可能没进去

该主题在最后一个回复创建后14天后自动关闭。不再允许新的回复。