1

我明白引用的工作原理有多弱,但我對它在ActionScript腳本事件監聽器中的使用感到困惑。考慮下面的例子:有關在actionscript監聽器中引用較弱的說明

public class Rectangle extends MovieClip { 
    public function Rectangle() { 
    var screen:Shape=new Shape(); 
    screen.addEventListener(MouseEvent.MOUSE_OUT, new Foo().listen, false, 0, true); 
    addChild(screen); 
    } 
} 

public class Foo extends MovieClip { 
    public function listen(e:MouseEvent):void { 
    trace("tracing");   
    }   
} 

現在這裏,因爲只有一個弱引用富,不會對事件偵聽器的Foo被垃圾收集,如果當垃圾收集器運行和停止代碼如預期的工作?

弱事件監聽器場景是否僅針對同一個類中的事件監聽器方法規定如下?

public class Rectangle extends MovieClip { 
    public function Rectangle() { 
    var screen:Shape=new Shape(); 
    screen..addEventListener(MouseEvent.MOUSE_OUT, listen, false, 0, true); 
    addChild(screen); 
    } 

    public function listen(e:MouseEvent):void { 
    trace("tracing");   
    } 
} 

在上面的場景中,這是多麼微弱的事件監聽器幫助?

如果Rectangle對象沒有其他引用,那麼它是垃圾收集的候選對象,但由於在對象內有一個事件偵聽器,事件調度程序會保留對該對象的引用,即使沒有其他引用到對象(除了由事件監聽器持有的對象之外)。因此它被阻止被垃圾收集。這就是弱事件聽衆被規定的原因嗎? Flash播放器是否如此幼稚以至於無法弄清楚事件監聽器是在同一個對象內定義的?

回答

3

Flash中垃圾收集的基本規則是,如果從時間軸引用(直接或間接)對象,則無法收集垃圾。這意味着如果您的類的實例沒有從根顯示列表中的任何地方引用(或者通過遞歸引用根的對象等),它將被收集,而不管它是否引用本身。

這也意味着兩個相互引用但不以任何方式從根顯示列表引用的對象應該有資格進行垃圾回收。

事件偵聽器中的弱引用選項主要是讓您不必手動刪除事件偵聽器。我個人傾向於不使用它,因爲我喜歡完全控制何時將對象標記爲垃圾回收。

因此,在您的第一個示例中,Foo實例在所有情況下都符合垃圾回收的條件。在你的第二個問題中,Rectangle實例是否可以被垃圾回收取決於它是否從顯示列表中引用。在這方面的標誌useWeakReference沒有區別。

從文檔here

類級別成員函數不屬於垃圾回收,這樣你就可以useWeakReference設置爲true類級別成員函數,而不對他們進行垃圾回收。如果爲嵌套內部函數的偵聽器設置useWeakReference爲true,則該函數將被垃圾收集並不再持久化。如果您創建對內部函數的引用(將其保存在另一個變量中),那麼它不會被垃圾收集並保持持久性。

+0

感謝您的回答。但是,正如你所說的,在上面的場景中,如果Foo有資格進行垃圾回收,那麼它是否違背了代碼的邏輯。就像在很多博客中一樣,將所有事件監聽器標記爲弱是一種很好的做法,但是在上述情況下,它不會導致錯誤,因爲我期望一直都會觸發單擊事件? –

+1

好吧,無論某些博客可能會說什麼,只有在有道理時才使用弱引用。如果需要將對象保存在內存中,請不要使用它。然而,我認爲你的例子有點奇怪,因爲你可能不應該首先創建一個像這樣的匿名對象。爲了垃圾收集的例子,它很好,但作爲實際的項目代碼,你應該重新考慮。 – richardolsson

相關問題