又一个关于新内存模型崩溃的问题

部分代码如下
for(var i = 0; i < data.length; ++i) {
var item = data[i];
var text = ccui.Text.create(item.id, “Arial”, 32);
text.setTouchEnabled(true);
text.addClickEventListener(function(item){
var scene = this.getScene(); // 此处点击却不能被回调,出错
scene.showHullInfoUI(item);
}.bind(this, item));
this._listView.pushBackCustomItem(text);
}

当使用新内存模型,并且触发GC时,点击text却崩溃, 说什么not function之类的。和下面的问题很像:
http://forum.cocos.com/t/cocosjs-3-11-1/37695
但是很不幸,我这个还是有问题。

我用的cocos2dx3.13.1 3.15.1 3.16均试过,都有问题。

我把Creator的引擎代码型过来创建工程模板,可惜出现cc.game未定义。
感觉只能回到旧内存模型。

旧内存模型更好用啊 内存释放及时 不容易崩 3.15.1 基本上不会崩溃了

ourbrander
你用的是新的内存模型,还是旧的内存模型?感觉新内存模型不太稳定。

一直用旧的内存模型

在3.15.1中,崩溃出现在如下的脚本代码 jsb_boot.js的apply调用处

// Original bind in Spidermonkey v33 will trigger object life cycle track issue in our memory model and cause crash
Function.prototype.bind = function (oThis) {
if (!cc.isFunction(this)) {
// closest thing possible to the ECMAScript 5
// internal IsCallable function
throw new TypeError(“Function.prototype.bind - what is trying to be bound is not callable”);
}

var aArgs = Array.prototype.slice.call(arguments, 1),
    fToBind = this,
    fNOP = function () {},
    fBound = function () {
        return fToBind.apply(this instanceof fNOP && oThis
            ? this
            : oThis,
            aArgs.concat(Array.prototype.slice.call(arguments)));
    };

fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();

return fBound;

};

从来么有在JSB里用过bind

感觉出在bind上面。
cocos3.15中的jsb_boot.js中的下面一行注释很奇怪
// Original bind in Spidermonkey v33 will trigger object life cycle track issue in our memory model and cause crash

另外,刚发现cocos2d-x的 3.13以上版本的spidermonkey都是v33
而creator的cocos中的spidermonkey却是v52的

看来creator和cocos2dx是分别维护的, creator中的jsb有可能比cocos2dx更经得起考验。我要尝试一下了

creator 1.7已改用 v8,是很值得期待的

主要是1.7不知道什么时候稳定。
上面的creator尝试过后,这次不是出现崩溃,而是出现 null is not a function之类的。
我推论出一个如下的结论,不知道是否正确
不能往纯c++对象中再注入一个脚本类型的成员变量,否则GC启动时会把这个对象清掉。我怀疑,返回的C++对象,有可能是脚本包装后的一个JS对象,而这个对象若不被脚本中的其它地方引用,是会被回收的。所以,注入的脚本成员变量,很可能在这个包装的临时JS对象中。
还要继续分析…

在creator 1.6.1的引擎内核中
主场景构造时如下代码

			this._listView = ccui.ListView.create();
			this._listView.setContentSize(this.getContentSize());
			this.setAnchorPoint(0.5, 0.5);
			this._listView.setPosition(0, 0);
			this.addChild(this._listView);
			var text = ccui.Text.create("error when clicked", "Arial", 32);
			text.setTouchEnabled(true);
			text.addClickEventListener(function() {
				console.log("should be called");
			}.bind(this));
			this._listView.pushBackCustomItem(text);

过段时间触发gc, 如主场景的onEnter中
cc.sys.garbageCollect();

点击文字时,出现
JS Exception: null is not a function, file: (null), lineno: 0
Stack:

希望能有解答…

已经得到解决,在新内存模型下要先执行如下脚本代码:

		(function(){
			if(ccui.ScrollView.oldInit == null) {
				var oldInit = ccui.ScrollView.oldInit = ccui.ScrollView.prototype.init;
				ccui.ScrollView.prototype.init = function() {
					oldInit.apply(this, [].slice.apply(arguments, [1]));
					var innerContainer = this.getInnerContainer();
					this.removeProtectedChild(innerContainer, false);
					this.addProtectedChild(innerContainer, 1, 1);
				};
				ccui.ScrollView.create = function() {
					var ret = new ccui.ScrollView();
					ret.init();
					return ret;
				};
			}
		})();
		(function(){
			if(ccui.ListView.oldInit == null) {
				var oldInit = ccui.ListView.oldInit = ccui.ListView.prototype.init;
				ccui.ListView.prototype.init = function() {
					oldInit.apply(this, [].slice.apply(arguments, [1]));
					var innerContainer = this.getInnerContainer();
					this.removeProtectedChild(innerContainer, false);
					this.addProtectedChild(innerContainer, 1, 1);
				};
				ccui.ListView.create = function() {
					var ret = new ccui.ListView();
					ret.init();
					return ret;
				};
			}
		})();