creator动态引用设计思考1:了解静态引用、动态引用

静态引用

比如场景的结构如下

游戏运行后bg.refCount=1,这个1的意思是场景中的bg.Sprite持有导致的。

现在主动把bg.Sprite.SpriteFrame=null,你会发现bg.refCount仍旧为1,这是因为Creator默认是静态引用,这样就会导致单场景的游戏越玩越卡。

Asset Manager 只会统计资源之间的 静态引用,并不能真实地反映资源在游戏中被动态引用的情况,动态引用 还需要开发者进行控制 以保证资源能够被正确释放。

cocos creator没有做动态引用的原因

  • JavaScript 是拥有垃圾回收机制的语言,会对其内存进行管理,在浏览器环境中引擎无法知道某个资源是否被销毁。

removeChildren时要遍历所有的children去释放资源, onDestroy是否可以解决

  • JavaScript 无法提供赋值运算符的重载,而引用计数的统计则高度依赖于赋值运算符的重载。

get/set 是否可以解决

动态引用

什么是动态引用

举例说明:

js 复制代码
const node = new cc.Node();
const sprite = node.addComponent(cc.Sprite);
sprite.SpriteFrame= xxx; // assets manager现在是无法感知到这个资源的引用增加了
scene.addChild(node);

解决方案1

这也是官方文档上给出的动态引用解决方案

js 复制代码
cc.resources.load('images/background', cc.Texture2D,
    (err, texture)=> {
        this texture = texture.
        // 当需要使用资源时增加其引用texture addRef();
        texture.addRef();
    }
);        

但是这样调用10次,ref就会+10次,如果使用人员有预加载的需求,只load不使用,显然上边的解决方案满足不了需求,如果addRef/decRef不配对使用,很容易造成内存泄露

解决办法2

这就需要参考cocos2dx中的retain/release,以Sprite举例,在sprite.SpriteFrame=textureoldRes.decRef/newRes.addRef

你可能会想到hack一下Asset的onLoad/_init之类的,加载prefab的时候,对所用到的资源addRef,但这个还是静态引用

对cocos2dx的动态引用的深入思考

当SpriteFrame加入到cache后,SpriteFrame.ref=1,表示只有缓存在持有。

此时SpriteFrame对应的Texture为2,一个是被cache引用(因为texture也要加入到cache中),一个是被SpriteFrame引用,

当SpriteFrame释放时,Texture才为1,此时只有cache引用.

这个设计是来自cocos2dx,因为他会检索被cache的引用,不是很好理解

我打算在新的设计当加入cache中时,不再dynamicRef+1

移植到creator的进一步思考

不能在asset.refCount上继续做文章,因为动态引用在这个基础上retain/relese,你是不知道当releaserefCount为多少时,才没有动态引用。

在静态引用的基础上就存在这个问题,不过官方也说明了,动态加载的资源refCount默认是0,理论是可以,但是我不建议。

我其实也是通过refCount==0判断asset是否存在静态引用,不过我为了易于维护的角度考虑,并且不干扰scene的资源自动释放逻辑

还是增加一个dynamicRef机制,也就是cocos2dx的那套机制

相关推荐
light blue bird16 分钟前
主子端台二分法任务汇总组件
前端·数据库·.net·桌面端winform
jeffwang1 小时前
我做了个让 AI 看屏幕跑测试的工具,因为 Playwright 测不了我的 Flutter Web
前端
HSunR2 小时前
dify 搭建ai作业批改流
开发语言·前端·javascript
代码不加糖2 小时前
2026 跨境电商独立站实战:从 0 到 1 搭建高转化 SaaS 商城(附源码)
开发语言·前端·javascript
亲亲小宝宝鸭2 小时前
拖一拖控件,拖出个问卷(低代码平台)
前端·低代码
江南十四行2 小时前
ReAct Agent 基本理论与项目实战(一)
前端·react.js·前端框架
We་ct3 小时前
LeetCode 72. 编辑距离:动态规划经典题解
前端·算法·leetcode·typescript·动态规划
小呆呆6663 小时前
Codex 穷鬼大救星
前端·人工智能·后端
当时只道寻常4 小时前
Vue3 + IntersectionObserver 实现高性能图片懒加载
前端
sakiko_4 小时前
UIKit学习笔记3-布局、滚动视图、隐藏或显示视图
前端·笔记·学习·objective-c·swift·uikit