【求助】Uncaught TypeError: Function is not a function和You are trying to destroy a object twice or more.

反馈时请提供以下信息:
–>

  • Creator 版本: 3.8.2
  • 目标平台:遨游浏览器/谷■浏览器(调试环境)、电报小程序webview环境(线上正式环境)
  • 重现方式:多次战斗,在完成一回合战斗之后退出战场后再进战场或者退出小程序后再进战场后,再开一回合的战斗,则大概率会在角色受伤的飘字出现时或者是怪物死亡时,开始报错。

报错截图如下:
bug1


上面两张图中的
Skeleton. destruct( 。。。
Skeleton._destroyImediate。。。
这个地方在不同的地方报错时,会有Layout /RichText两个组件的可能性

大部分的报错集中在播放角色受击动画之后的死亡动画播放结束时发生的。
代码逻辑顺序是:
1.在受击方法中,设置受击动画,当动画播放结束时会调用回调函数endCB的,
2.endCB箭头方法中判断血量低于0时则播放死亡动画的方法PlayDead

3.在死亡动画播放结束后,先隐藏节点,再延迟0.2秒调用(本来是直接采用下一帧再销毁的,因为报错所以改成延迟0.2秒,依然会报错)


我想请教的就是Function is not a function这个报错,来自_virtual_cc-431a5be6.js脚本中的12499行,代码大致如下:

{
          var func = '';
          for (key in propsToReset) {
            var statement = void 0;
            if (CCClass.IDENTIFIER_RE.test(key)) {
              statement = "o." + key + "=";
            } else {
              statement = "o[" + CCClass.escapeForJS(key) + "]=";
            }
            var val = propsToReset[key];
            if (val === '') {
              val = '""';
            }
            func += statement + val + ";\n";
          }
          return Function('o', func);//<<------------------此处的报错
        }

这个Function 按道理是关键词,是不可能不算功能方法的吧?
而下面几行则是从12526行开始的跟预销毁有关的代码,也是报错涉及到的:

    var _proto = CCObject.prototype;
    _proto.destroy = function destroy() {
      if (this._objFlags & Destroyed$2) {
        warnID(5000);
        return false;
      }
      if (this._objFlags & ToDestroy) {
        return false;
      }
      this._objFlags |= ToDestroy;
      objectsToDestroy.push(this);
      return true;
    };
    _proto._destruct = function _destruct() {
      var ctor = this.constructor;
      var destruct = ctor.__destruct__;
      if (!destruct) {
        destruct = compileDestruct(this, ctor);
        value(ctor, '__destruct__', destruct, true);
      }
      destruct(this);
    };
    _proto._destroyImmediate = function _destroyImmediate() {
      var _onPreDestroy, _ref;
      if (this._objFlags & Destroyed$2) {
        errorID(5000);
        return;
      }
      (_onPreDestroy = (_ref = this)._onPreDestroy) === null || _onPreDestroy === void 0 ? void 0 : _onPreDestroy.call(_ref);
      {
        this._destruct();
      }
      this._objFlags |= Destroyed$2;
    };

跟“You are trying to destroy a object twice or more.”这个报错直接相关。但是我的代码里面,检查不出来哪里会存在重复销毁的起点。

最神奇的是,这个bug在我的电脑遨游浏览器网页上和电脑版软件小程序环境中触发的概率不高,但是在同事的环境中几乎必现。
估计是这种bug太少见了,论坛也没有记录,实在搞不定了,求助万能的网友大佬了。

会不会是作用域的问题,你把这个Function改成endCb:()=>void = null 试试

或者你检查一下传进去的endCb类型对不对,打印一下传进去的endCb

endCB是回调函数,无所谓类型对不对的。
主要是节点销毁的时候太慢了,或者说是销毁的时候应该是先销毁所有子节点的组件,最后再去销毁父节点的。看报错的方法名,感觉就是预销毁的时候出问题了,帧调用多次销毁了就报重复销毁的错了。
目前是不销毁了,直接false加移出父节点,让js去做■■回收了。