Cocos Creator v1.8.2 测试版发布帖(2月13日更新 rc.2)

这块 MenuItem 如果 重复设置多个callback是有可能。
但是在 creator 中 MenuItem 已经没有使用的吧,只是历史原因,绑定代码还留在那里。

其他地方,比如 cc.callFunc(…) 这种回调函数的绑定,回调函数都只是设置一次的情况吧。
如果会设置多次,这里可能是需要再做调整,把旧的 func 从 this 对象中移除。

我只是想知道我的推测是否正确。如果这样,那么我需要对生成后的绑定代码进行二次处理。主要是两个:

  1. 设置回调函数时需要对jsFunc进行root, 但不对jsThis进行root; 回调函数被析构,也就是lamda函数被析构时,需要对jsFunc进行unroot。其实类似于2dx中的JSFunctioWrapper类所做的事情,但不完全一样。
  2. 对jsb.registerNativeRef和jsb.unregisterNativeRef函数进行改造,增加对计数的支持,即如果两次root, 就需要两次的unroot才能解除绑定关系。
    看看这个方式有没有问题。

能否提供一个你们复现出问题的使用场景?因为我搜索引擎内部的所有attachObject函数,理论上不应该出现多次调用的情况。而且只有在非常极端的情况下,才会导致内存泄露,因为 this 是可控的,可被回收的。这块如果没有确切的代码编写方式验证出此问题,我们不会断然修改这块,毕竟影响的面比较广。

当初回调函数使用 attachObject 的原因是,不希望引入 root 导致内存泄露

// 假定 AClass 是一个cpp<->JS绑定类,其有一个 setCallback 的绑定方法,setCallback 接受 func 和 target 参数。

var BClass = function(aobj) {
    this.aobj = aobj;
}

var AObject = new AClass();
AObject.setCallback((function() {
    var self = AObject; // 匿名函数引用了外部的AObject,导致 AObject 可能无法被GC
    // 如果这个匿名函数是被root住的,那么self这个变量就永远不会被释放,即无法触发AObject的c++层的析构函数,
    // 进而导致 c++ 的AClass 内的std::function<> 无法被释放,就没法使用lambda对 se::Value 关联的 se::Object 进行 unroot 操作
    // 进而导致更加严重的内存泄露问题。

}, someObject););

var BObject = new BClass(AObject);

基于上面的考虑,我们才用 attachObject 的方式。但是你说的的确可能是个问题,但是并不会导致非常严重的问题,因为在你说的极端情况下,func被引用多次的话,this 还是能被gc控制的,只要this被释放,对应的func也是被释放的。
除非有确认哪个api调用的确产生了严重问题,我们会考虑单独为这个api做一下手动绑定修复。

目前 jsb.registerNativeRef 如果target 对象是同一个,是直接复制替换的,旧的对象会被替换掉。

https://github.com/cocos-creator/cocos2d-x-lite/blob/v1.8-release/cocos/scripting/js-bindings/script/jsb_prepare.js#L244

registerNativeRef 的设计初衷是类似管理js对象生命周期使用,跟root unroot并没有直接关系。

明白,多次attachObject的情况应该不多,目前还没有碰到,也确实极低情况会碰到,这个问题不大。

为你认真阅读文档与代码点赞。:+1:

我觉得有个方案,你们看下是否可行,或者是否有问题。
关于C++访问JS函数被GC掉的问题,其实也就两个情况,其中一个,也就是最主要的,就是C++的回调函数的绑定问题。把root/unroot/attachObject/detachObject做计数机制, 然后绑定代码的C++闭包函数构造时,对相应的JSFunc进行root, 闭包函数析构时,对JSFunc进行unroot, 使用shared_ptr就可以办到,类似JSFunctionWrapper。这样,只要闭包函数的生命期未结束,JSFunc就一定不会被GC。这个方案的好处,就是安全可控,适应各种复杂情况和极端情况,并且还简单。并且不需要在C++对象中添加那些retainScriptObject/releaseScriptObject代码。很多项目,特别是网游项目的逻辑代码都很复杂,各种稀奇古怪的脚本代码都有。
另一种情况是JS中派生C++类的情况,这个还是需要retainScriptObject/releaseScriptObject。

有个问题问下,C++的绑定代码中如何抛出脚本异常。

SE_REPORT_ERROR("wrong number of arguments: %d, expected: %s", argc, ">=3");

这个代码,只会输出

jsb: ERROR: File ..\manual\jsb_node.cpp: Line: 1255, Function: js_cocos2dx_Scheduler_schedule
Converting 'interval' argument failed
E/jswrapper (1297): [ERROR] Failed to invoke js_cocos2dx_Scheduler_schedule, location: ..\manual\jsb_node.cpp:1297
D/WebSocket.cpp (1423): WebSocket (0C9D7398) Unhandled websocket event: 33

这个信息不能知道脚本层面的哪个代码导致的。

@jare 昨天我下的v1.8.2-rc.2 win版本的然后安装一直报错 提示已经安装了最新的 但是打开还是1.8.1 然后我就删除了所有和creator有关的文件(主要是卸载没反应) 然后重启了还是提示已经安装了最新的 现在我机子不知道要怎么装这个版本了

为什么卸载会没反应?清理一下注册表看看,应该是安装有残留引起的。

正式版快了吗,1.8.1有点不爽,有些莫名其妙的问题

需要清理哪些注册表哈 有目录吗

好吧,确实如此。不用root/unroot, 而用attachObject/detachObject呢?闭包生成的时候就attachObject, 闭包被销毁的时候就detachObject,同样加上计数器机制。但这样的问题就是,需要建立起retainScriptObject和releaseScriptObject了。

cc.game.EVENT_HIDE/cc.game.EVENT_SHOW 监听后在前后台切换时会收到两次重复的事件
engine是同步了github上1.8 release分支最新代码

1.10 会修复~

模拟器好多错误,getXMLHttpRequest请求根本得不到正确返回值! 这块有大问题,而且不支持options模式,对原生支持的不好。 能不能集成微信登录 分享接口,和原生麦克风什么的。这样方便了开发者完全不用担心别的,只需要写JS就可以了!

现在棋牌游戏 都需要微信登录 和 录音功能

请问1.8.2修复以下问题了吗:

打包微信小小游戏后,把res文件夹放到远程资源服务器上,在使用cc.loader.load加载网络图片时,加载失败,remoteUrl错了,自动在前面加了远程资源服务器的地址。例如,本来我是要加载头像地址http://abc.com/111.jpg ,我的存放远程资源的服务器地址是 https://remote-res/ ,当在代码中调用cc.loader.load({url: remoteUrl, type: ‘jpg’}时,remoteUrl自动变为了https://remote-res/http://abc.com/111.jpg 导致加载失败。

正式版还要多久????