[代码相关]访问单例中修改过的变量不一定有正确返回结果

假如有一个继承自cc.Component的单例,它被挂载在了一个不被销毁的节点上(因为需要在onLoad里注册事件)。
单例中有两个变量,一个cc.Node类型,一个number类型;有两个方法来获取两个变量的值(return this.变量;)。
两个方法中对变量的赋值都是采用this.xxx = XXX;而不是instance.xxx = XXX;
当其他脚本去获取单例访问单例中的变量时(单例.instance.方法),cc.Node的变量能正常访问,number的类型变量却一直是默认值。

疑惑有三点:
1.为什么number类型的变量一直是默认值,cc.Node类型的是正常的。跟值类型和引用类型是否相关?
2.尝试过单例中的方法用instance.xxx = XXX;方式赋值,会解决本贴的问题,但是单例中对自己的变量赋值还要写上自己的名字,感觉太奇怪了。
3.单例好像不是唯一的,可能由于是挂载的单例,感觉引擎启动的时候有一个副本,外部访问instance的时候有一个

单例代码:

const { ccclass } = cc._decorator;

@ccclass
export class LevelManager extends cc.Component {

    public static readonly instance = new LevelManager();

    private theNumber: number = 0;
    private theNode: cc.Node = null;

    update(dt: number) {
        this.theNumber++;
    }

    public getNumber(): number {
        return this.theNumber;
    }

    public getNode(): cc.Node {

        if (this.theNode == null) {
            this.theNode = cc.find("New Node");
        }
        return this.theNode;
    }
}

调用代码:

import { LevelManager } from "./LevelManager";

const { ccclass, property } = cc._decorator;

@ccclass
export default class Helloworld extends cc.Component {

    @property(cc.Label)
    label1: cc.Label = null;

    @property(cc.Label)
    label2: cc.Label = null;

    start() {
        this.scheduleOnce(() => {
            this.label1.string = LevelManager.instance.getNode().name;
            this.label2.string = LevelManager.instance.getNumber().toString();
        }, 3);
    }
}

论坛里搜索过单例和bind之类的,没有我遇到的这种困惑。
希望明白人来给解下惑。
晚些时候补充Demo。NewProject.zip (827.1 KB)

我觉得你这种单例的写法有问题。
public static readonly instance = new LevelManager();
这里不应该直接new LevelManager();因为你本身LevelManager挂载到节点上时,已经生成了一个LevelManager的对象。你这里new的LevelManager并不是你期望的单例。这就解释了为什么你用instance.getNumber()获得的永远是初始值。因为这个instance并不是当前的脚本中的this。而你getNode()时this.theNode = cc.find(“New Node”);这句代码,确保了即使是其他对象也可以获取到正确的Node。

正确的写法应该是在onLoad中对instance进行赋值。LevelManager.instance = this;这样才是单例。

3赞

感谢回复