[LayaAir3]Pool对象池获取继承对象时会返回基类对象

const { regClass, property } = Laya;

@regClass()
export class Main extends Laya.Script
{

onStart()
{
let item1 = Laya.Pool.createByClass(TestClass);
console.log('item1:', item1.type);
Laya.Pool.recoverByClass(item1);
let item2 = Laya.Pool.createByClass(TestClass2);
console.log('item2:', item2.type);
console.log(item1 == item2);
}
}
export class TestClass
{
type = 0;
}
export class TestClass2 extends TestClass
{
constructor()
{
super();
this.type = 1;
}
}
测试代码如上所示,打印结果是:0,0,true,预期结果是:0,1,false才对。

poolBug.png

获取TestClass2实例时,返回的是TestClass的实例对象,看了下源码,发现是获取类唯一标志时出了问题
/**
* 返回类的唯一标识
*/
private static _getClassSign(cla: any): string {
var className = cla["__className"] || cla["_$gid"];
if (!className) {
cla["_$gid"] = className = Pool._CLSID + "";
Pool._CLSID++;
}
return className;
}
cla["__className"] || cla["_$gid"]这种写法会查找父类的属性,导致父类和子类返回了同一标志,让对象池混乱了
这个问题2.0版本也存在,现在只能手动给每个类添加__className规避,希望能尽快修复
已邀请:

layabox

赞同来自:

这个Pool的特性已经存在很久,或者说,是否本来就有传基类能够返回扩展类对象的需求,最初的设计者已不在团队中,无人得知,所以当前修改这个,对我们来说是存在风险的,而且它只是一个工具类,如果开发者存在其它需求,可以写个自己的Pool类,不使用这个引擎内置的。

之肖

赞同来自:

看了下根据类回收这个方法,发现也有问题
/**
* @en Recover by class name if the class has one, if not, do not recover.
* @param instance The instance of the class.
* @ZH 根据类名进行回收,如果类有类名才进行回收,没有则不回收。
* @param instance 类的具体实例。
*/
static recoverByClass(instance: any): void {
if (instance) {
var className: string = instance["__className"] || instance.constructor._$gid;
if (className) Pool.recover(className, instance);
}
}

instance["__className"]这是获取实例属性,不是获取类静态属性,估计是手滑写错了
实际上,没必要去写instance["__className"] || instance.constructor._$gid
因为Pool上有_getClassSign这个方法,直接调用_getClassSign(instance.constructor)来获取就行了,前提是_getClassSign这个方法内部实现先修复下
 

该问题目前已经被锁定, 无法添加新回复

商务合作
商务合作