对于小游戏来说,单个场景的页面可以事先写好然后用active的方式来开关。
但是这会导致一个严重的问题就是每次载入这个场景的时候就会很卡,而如果是让场景绑定预制体资源的时候这个场景同时也会加载对应的预制体资源,同样会导致很卡。
既然这样的话只有通过cc.loader来加载资源是具有效率的一种方式,不过要注意,预制体资源需要放在resources文件夹里面。
let self = this;
cc.loader.loadRes(url, function (err, prefab) {
if (err == null && prefab){
var node:cc.Node = cc.instantiate(prefab);
if (node){
self._father.addChild(node); //这边要注意的一点,在cc.loader里面加载不要用this,
}
}
else{
cc.warn(err + " name load error!!!");
}
});
但是这个预制体是要关闭的。当需要关闭的时候便可以直接删除预制体就可以了,操作如下
node.destroy();//直接销毁节点,最具有效率的方式
node.removeFromParent();//移除与父节点的引用
一般而言只要destroy就可以了,但是随着预制体节点变多,很容易在预制体内容较多的情况下发生卡顿,所以在这里需要找到一个更好的解决方案
CocosCreator 和 Cocos2d-x在对象的内存管理上是完全不同的.
因为c++没有自动内存管理, 谁申请内存谁负责释放内存(堆内存), 这是非常容易出错的, Cocos2d-x使用引用计数来做内存管理, 主要通过对象的容器(对象数组/对象字典)来做计数增减, 节点树就是这样一个容器. 所以节点树可以管理节点对象的内存生命周期. cocos2d-lua/js 虽然是脚本语言, 语言本身是有自动内存管理的, 但是节点的内存还是c++管理.
而creator因为要做h5游戏, 必须要用js做节点的内存管理, 为了统一接口, 在native上也使用js的内存管理.
而js的内存管理很简单, 一个对象没有引用, 它就会被销毁回收. 但是如何保证节点对象没有被引用呢? 一个节点被移除节点树,没有执行action, 没有事件监听, 除了本身挂载的脚本组件外没有被其它脚本引用, 那么就可以认为没有被引用, 垃圾回收会回收对象内存.
destroy会删除所有的action和事件监听, 所以调用destroy删除节点是有效的做法.
--------此段引用自this.node.removeFromParent(); 删不干净
如若是预制体上有很多粒子效果,缓存,则需要用一个对象储存遍历该预制体所有cc.components,首先逐一删除其他然后再删除缓存
releaseAsset(url:string){
if (cc.sys.isBrowser)return;
if (this.releaseObjs[url] || url == null)return;
this.releaseObjs[url] = 1;
if (url.indexOf("/ico/")){
this._textCache.push(url);
return;
}
cc.loader.removeItem(url); //据说删除有用
var deps = cc.loader.getDependsRecursively(url);//获取某个已经加载好的资源的所有依赖资源,包含它自身,并保存在数组中返回。
if (deps != null){
for (var i = 0; i < deps.length; i++){
if (deps[i] == null)continue;
if (deps[i].indexOf("json") != -1 || deps[i].indexOf("/ui/common/") != -1 ||
deps[i].indexOf("/particle/") != -1 || deps[i].indexOf("/temp/") != -1 ||
deps[i].indexOf("/ui/main/") != -1 || deps[i].indexOf("/ui/icon/") != -1){
continue;
}
if (deps[i].indexOf('json') == -1 || deps[i].indexOf("/spine/") != -1){
this._textCache.push(deps[i]);
}
}
}
cc.loader.releaseRes(url);//释放通过 loadRes 加载的资源。
}
//删除记录的没用的缓存文件
releaseBgAsset(){
for (var i = 0; i < this._textCache.length; i++){
cc.loader.removeItem(this._textCache[i]);
cc.loader.release(this._textCache[i]);
}
this._textCache = [];
}
实际上,使用cc.loader删除是删的最干净的选择