2010-05-19 29 views
0

在我的fla文件的一個框架(我們稱之爲框架2)中,我加載了幾個xml文件,然後將該數據發送到在該框架中初始化的類中,該類創建了幾個定時器和偵聽器。我正在做AS3參考清理嗎?

然後,當這個類完成這個工作。我調用dispatchEvent並移動到第3幀。此幀也執行一些操作,它已初始化並創建了一些事件偵聽器和計時器。完成後,我再次移動到第2幀。

這應該重複一次,因爲我需要,所以我需要清理引用正確,我想知道如果我做得正確。

對於精靈我做到這一點。

world.removeChild(Background); // world is the parent stage 
Background = null; 

對於其他類的實例,我這樣做。

Players[i].cleanUp(world); // do any cleanup within the instanced class 
world.removeChild(PlayersSelect[i]); 

對於事件監聽者,我這樣做。

if(Background != null) 
{ 
    Background.removeEventListener(MouseEvent.CLICK, deSelectPlayer); 
} 

對於計時器我這樣做。

if(Timeout != null) 
{ 
    Timeout.stop(); 
    Timeout.removeEventListener(TimerEvent.TIMER, queueHandler); 
    Timeout.removeEventListener(TimerEvent.TIMER_COMPLETE, queueCompleted); 
    Timeout = null; 
} 

而對於庫圖片我這樣做

if(_libImage!= null) 
{ 
    s.removeChild(Images._libImage); // s is the stage 
    _libImage= null; 
} 

而對於類本身主時間軸,我這樣做

Frame2.removeEventListener("Done", IAmDone); 
Frame2.cleanUp(); // the cleanup() does all the stuff above 
Frame2= null; 

即使我做這一切,當我第二次進入第二幀,運行1-2秒,然後我得到很多空引用錯誤,因爲清理函數被過早地調用。

我正在清理嗎?

什麼會導致事件過早起火?

回答

2

對我來說,最大的問題是清理你正在做的聽衆。爲了避免在偵聽器清理中出現任何錯誤,我總是檢查該項是否存在,然後是否有偵聽器;因此:

if(item) 
{ 
    if(item.hasEventListener(MouseEvent.CLICK)) 
    { 
     item.removeEventListener(MouseEvent.CLICK,doSomething); 
    } 
} 

我取出一個孩子之前做simimlar檢查:

if(item) 
{ 
    if(this.contains(item)) 
    { 
     this.removeChild(item); 
     item.destroy()//or whatever you code is to clear that element of its own dependencies. 
     item = null; 
    } 
} 
+0

刪除不存在的偵聽器不應該拋出錯誤。 – quoo 2010-05-19 21:46:13

+0

謝謝。我發現這個錯誤,不是我懷疑的,但是你幫助我看看其他人如何清楚地引用。 – 2010-05-19 21:52:49

+0

@jordanx。這個檢查'if(this.contains(item))'是錯誤的。該代碼可能會引發錯誤。 'contains'方法檢查DisplayObject B是否是DisplayObjectContainer A的後代。但是,只有B是A的「直接」子元素(即A是B的父元素),removeChild纔有效。大多數情況下,這是有效的,但這是一個潛在的錯誤。正確的方法是(假設你已經檢查過項目是一個非空的DPO):'if(item.parent == this)'。 – 2010-05-21 02:33:51

0

如果你希望能夠您將其設置爲空後,讓垃圾回收器來清理你的對象。 然後,當您添加一個eventListener時,使用一個弱引用,這允許垃圾收集器在其值爲null時收集它。 見的addEventListener函數的參數:

addEventListener(type:String, 
       listener:Function, 
       useCapture:Boolean = false, 
       priority:int = 0, 
       useWeakReference:Boolean = false) 

所以對你沒有空引用,您必須將最後一個參數設置爲false。

addEventListener(MouseEvent.MOUSE_OVER, function(), false, 0, true); 
instead of 
addEventListener(MouseEvent.MOUSE_OVER, function()); 

當你有你與removeEventLister功能,手動刪除它們強引用事件監聽器去除引用的對象之前。

編輯: jordanx的示例無效,因爲即使item爲null,強引用仍然存在,並且空指針仍可能發生。