当界面内加载一个预制体A,没加载完毕界面就被关闭了,关闭的界面设置parent=null;
那预制体A,就一直是失活状态,当界面被销毁了,预制体A就调不到onDestroy,这样的话,我如何减少预制体A的引用呢
节点已销毁
1、简单粗暴,发现节点被销毁,直接释放
xxBundle.load(url, cc.Prefab, (err, APrefab) => {
if(!isValid(node)) {
// 通过这种方式直接释放
APrefab.addRef();
APrefab.decRef(true);
}
})
2、发现节点被销毁,延迟释放
xxBundle.load(url, cc.Prefab, (err, APrefab) => {
if(!isValid(node)) {
// 通过这种方式直接释放
APrefab.addRef();
Your_Auto_Release_Ref_Pool.push(APrefab)
}
})
// Your_Auto_Release_Ref_Pool 根据策略,自动释放
Your_Auto_Release_Ref_Pool.prototype.Release = function() {
let toReleases: Asset[] = GET_TO_RELEASE_ASSETS();
toReleases.forEach(a => a.decRef(true))
}
节点没销毁
xxBundle.load(url, cc.Prefab, (err, APrefab) => {
if(isValid(node)) {
// 引用住,节点销毁时释放。
APrefab.addRef();
(node.getComponent(AutoDestroy) || node.addComponent(AutoDestroy)).addDestroyFunc(()=> {
APrefab.decRef(true);
})
}
})
谁便举例了几个,可以参考下大致的思路。
最重要的是,使用起来一定要方便。因此要封装成底层的 API,或者组件,上层使用的时候,不关心内部实现,而且可调整缓存和释放策略。
这个是加载完毕时候的发现销毁时候的回调,那如果加载完毕的时候已经加入了没有激活的父节点,当父节点销毁的时候,就调不到了
那问题来了,那个节点既然未激活,你的加载为什么要开始呢?
或者你的释放,为什么又要绑定到一个未激活的节点上?你的设计是否有问题
比如界面里面,需要 加载一个按钮,按钮是挂在了界面内的一个子节点里面,打开界面立马加载了,加载时间比如需要3秒,我在3秒内关掉了界面。那这样动态加载的预制体都需要判断所加入的节点是否是激活状态(activeInHierarchy)?会不会有点麻烦呢
封装好就不麻烦。
另外一个,不是判断激活状态。
最后,界面加载,最好是放在顶层那个界面负责加载。给你看个我最后封装成这样的方式:
界面依赖一个资源集合的方式:
资源集合中依赖界面预制体、图片、音频、图集,还能自定义解析:
这样资源依赖写顶层。释放也由顶层来负责。
非常动态的内容,比如列表滚动过程加载释放,通过特定组件去封装加载,写好一次,后续就不麻烦。
您说的顶层是 在需要加载的界面写一个 加载 和 释放 的静态函数吗?然后手动调用释放和销毁?
是 ui.open(界面)的时候,ui 管理模块会创建资源收集器,去收集依赖资源,然后加载,然后根据界面释放情况,去决定资源的释放是立即释放,还是绑定到界面的 onDestory 去。。。
我的这个静态 R 函数,就是收集过程中,由 ui 管理器负责递归调用的。
啊,了解了你的意思了。那这样子处理的话,不是提前加载页面所有所需的资源了吗?比如界面中有3个页面,进入界面的时候只需要显示第一个页面,那就不需要加载后2个页面了。不过您这样子确实避免了上述我所说的问题
那就不添加动态加载的那 2 个资源
那 2 个资源,单独创建加载器去加载。
这种是提供了一种界面打开就加载所有依赖的能力。怎么用,是由人决定的。。。

您的做法和我以前Laya的产品很像。嘻嘻。现在新项目想着不人为收集,我再斟酌一下,应该可以避免一下。谢谢您给的提醒
是的。目前是这样子用的。使用的时候仅需要一个名字就可以加载并且使用了。只是目前您比我多了这个,释放起来就更方便
这是我们目前直接在代码里面使用的

你这样用起来会比较难受,尤其是界面中的子节点
因为要 instantiate 的时候,没有马上出来,出现异步操作,一定要判定父节点是否已销毁。其实是很难受的。
是的,这里在回收时候时候有点难受。但是业务用起来其实舒服。已经太多用的地方了,看看能不能挽回
嗯,如果没有节点提前销毁的话,你这用起来其实还是比我这个更舒服。
不过因为每个界面只需要收集自己的依赖资源即可,而依赖资源又依赖哪些资源,那是依赖资源自己的事情,收集流程会完成依赖资源的递归收集。因此,收集代码和使用代码写在同一个文件里的两个位置,整体还是能接受的。




