RichText的onDestroy的意义在哪里?

根据node的销毁逻辑,在调用component前已经提前把所有的子节点destroy掉了。


然后这个时候在执行RichText组件的onDestroy()

put的时候有个检测

image
所以节点根本就回不到池子中。

第二个问题:

        let children = this.node.children;
        for (let i = children.length - 1; i >= 0; i--) {
            let child = children[i];
            if (child.name === RichTextChildName || child.name === RichTextChildImageName) {
                if (child.parent === this.node) {
                    child.parent = null;
                }
                else {
                    // In case child.parent !== this.node, child cannot be removed from children
                    children.splice(i, 1);
                }
                if (child.name === RichTextChildName) {
                    pool.put(child);
                }
            }
        }

根据节点池的代码:
池子的长度是20

/**
 * 富文本池。<br/>
 */
const labelPool = new js.Pool((seg: ISegment) => {
    if (DEV) {
        assert(!seg.node.parent, 'Recycling node\'s parent should be null!');
    }
    if (!cclegacy.isValid(seg.node)) {
        return false;
    } else {
        const outline = seg.node.getComponent(LabelOutline);
        if (outline) {
            outline.width = 0;
        }
    }
    return true;
}, 20);

往池子回收的时候:

/**
 * !#en Put an object into the pool.
 * !#zh 向对象池返还一个不再需要的对象。
 * @method put
 */
Pool.prototype.put = function (obj) {
    var pool = this._pool;
    if (this.count < pool.length) {
        if (this._cleanup && this._cleanup(obj) === false) {
            return;
        }
        pool[this.count] = obj;
        ++this.count;
    }
};

“this.count < pool.length” 池子已经满的时候,回来并没有对node执行destory操作。


根据文档,是不是泄露了?

1赞


我也补一个吧,_labelSegmentsCache里在onDestroy的时候没有释放,从一个很长的文本切成很短的时候,这个cache里会有节点

都已经销毁了不放入对象池很正常啊,不然下次取出来也用不了

第二个问题,当取出的数量超过20个后,就不会再从池子中取了,而是会new吧,对于多出来的obj,上层应该是执行的destroy而不是put吧 :thinking:没怎么用过引擎的nodePool,但这块应该是这么个逻辑。

所以onDestroy这块代码就没有意义了啊。

不是取,是塞。执行塞了,但是没塞进去。

塞之前有没有判断count呢?

代码都贴出来了啊~~

@jare 能确认下这个问题吗?

确实,这个onDestroy是在所有销毁后才触发的,以前我一直以为是在开始销毁前执行的 :joy:

而且从第一个版本开是到3.8的版本,一直保持着这段代码~~!

onDestroy本来设定就是销毁后才会触发的,如果需要销毁前先执行你的逻辑,可以重写destroy方法,在执行父类的destroy之前执行你的逻辑:
image

你说的我都知道啊。

我只是指出源码中的疑惑。