2017-07-16 43 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