2017-07-16 47 views
0

我有一个按钮数组,我附加了这样的事件监听器。Actionscript:为什么这个Event Listener导致大量的内存消耗

arr[c].addEventListener(MouseEvent.MOUSE_UP, Proxy.go(this, click, Model.categoriesListXml.category_0[i].category_1[j][email protected]_id, Model.categoriesListXml.category_0[i].category_1[j][email protected])); 

其中150个使用了32MB的内存。

当我用下面的内存下降到2MB。

var categoryId:String = Model.categoriesListXml.category_0[i].category_1[j][email protected]_id; 
var name:String = Model.categoriesListXml.category_0[i].category_1[j][email protected]; 
arr[c].addEventListener(MouseEvent.MOUSE_UP, Proxy.go(this, click, categoryId, name)); 

我所做的只是在事件监听器中使用之前将xml元素放入自己的变量中。

有谁知道为什么会发生这种情况?

我的猜测是整个XML对象被包含而不仅仅是我需要的元素。

回答

4

我认为它的工作原理如下。

试试。当处理任何东西时,Flash非常懒惰XML -related。实际上,它实际上很懒,它甚至有System.disposeXML(...)方法,因为否则即使您有意识地删除对它的每一个引用,也可能不会垃圾收集对象。

Catch。理解这一点很重要,即最XML操作导致XML的XMLList对象,说

// XML source. 
var X:XML = <root a="1" />; 

// You might think it returns String, but no, it is just autocast to String. 
var a:String = [email protected]; 

// If you don't specify data type, this returns XMLList object of length 1, 
// with an XML member of type "attribute", name "a" (or maybe "@a"), and so on. 
var A:* = [email protected]; 

因此,没有明确铸造你的属性字符串你通过2 的XMLList对象作为函数参数来代替(或者看起来)。

最后。只看Proxy.go(...)告诉我们,它创建一个delegate(这是一种closure),一个未命名的未绑定函数与存储的参数列表。它应类似于此:

public function go(target:Object, method:Function, ...rest:Array):Function 
{ 
    return function():void 
    { 
     method.apply(target, rest); 
    } 
} 

这个工程由于ECMA标准,允许关闭访问所有的父类的方法的数据(可能与的JavaScript也有效):局部变量和方法参数。

所以,你有它。一些未命名的函数会在玩家的记忆中某处保留(非常永远)一个无类型参数列表,其中包含您的对象(这些对象是持久的,不易处理的)。然后你用这种方法创建150个这样的怪物。记忆在喷泉和尼亚加拉斯泄漏是很自然的。

+0

@Organic,感谢您的全面解释,这是有道理的。所以我在听众中尝试了.toString,这也解决了内存问题。 – Mar