请教大佬,像这种情况,代码怎么写才不会循环引用?

test.zip (1.4 KB) test.zip (1.4 KB)
上面有两个类,类A用来管理释放B类的单例对象,
类B有时需要调用类A的一些方法
请问我如何写,才能避免循环引用呢?
我现在只能在类A中搞个function指针,指向类B的destoryInstance方法,这样实现有点恶心。。释放时去调用。。

B 类提供回调接口,由A实现

使用接口编程 即可解耦

这个TypeScript没有像c++那种,可以直接 class classB;?来避免循环引用的方法?这太蛋疼了吧

声明一个接口类把你要的接口放进去,把B继承接口A持有接口类型

接口只能声明实例方法吧?

接口只能声明实例成员、方法吧?静态方法没法声明吧?

:joy:通常B应该不允许访问A,但是如果真的要访问,也许应该把要访问的东西给独立出去吧。

你这类设计的就有问题,莫名其妙,不知道什么作用test 2.zip (2.1 KB)

循环引用问题的本质是:定义A的时候需要B,而定义B的时候又需要A,导致定义B的时候查找A的定义是空。
所以解决方案是,设计代码结构的时候,避免定义的时候互相引用即可。
至于你在各自的函数里互相勾搭一点问题没有。
按着这个原则一般不会有问题。

另外有个现象还没考究原因,我发现ccc里会循环引用的代码,在NodeJS里是能正确编译的,不知道是TS版本问题还是commonJS和ESM的区别。

就是想知道有什么办法解决循环引用。。这只是个简单的demo

循环引用的本质是不为空的指针的互相引用,在引用计数检测时,会导致引用计数无法减为0的情况,在javascript里,互相导入脚本文件是不合理的,在ts中import做了一些处理,所以简单的引用是可以被语言自身处理掉,但是还是要尽力避免,因为复杂的互相引用脚本文件还是可能存在因循环引用出错的情况,在代码设计中都要考虑到这一点。

any 可以解决 要么就是回调回去

用any,那直接用js得了

哦,我没看他说的是释放问题。我说的是编译时的循环引用。

释放问题几乎没有讨论的必要了吧,就是个最基本的设计问题,属于基础中的基础了。

不怕麻烦可以在关键类 对其引用的类用上延时加载 可以大幅度抑制出现循环引用的概率
type A= import("./A").default;
var A: typeof import("./A").default = null;
cc.game.on(cc.game.EVENT_GAME_INITED, async () => {
A= (await import("./A")).default;
});

可以用代理的方法来解决循环引用的问题