2008-10-17 35 views
2

我有一個字典,我爲movieclips保存數據,如果我停止使用動畫片段,我希望數據被垃圾收集。我正在使用弱密鑰參數,並且與其他數據完美協作,但是我遇到了一個問題。MovieClip沒有從字典中刪除

此代碼的偉大工程:

var mc = new MovieClip(); 
var dic = new Dictionary(true); 
dic[mc] = 12; 
mc = null; 
System.gc(); 
System.gc(); 
for (var obj in dic) 
    trace(obj); //this doesn't execute 

但當我實際使用的影片剪輯,它停止工作:

var mc = new MovieClip(); 
var dic = new Dictionary(true); 
dic[mc] = 12; 
addChild(mc); 
removeChild(mc); 
mc = null; 
System.gc(); 
System.gc(); 
for (var obj in dic) 
    trace(obj); //this prints [object Movieclip] 

爲什麼會出現這種情況?這是我做錯了什麼嗎?有沒有解決方法?

編輯:我知道這個具體的例子我可以使用delete dic[mc],但當然這是一個簡單的例子。一般來說,我不想手動從字典中刪除動畫片段,但它應該是自動的,當我在應用程序的其餘部分不再引用它時應該是自動的。

EDIT2:我想檢測一下亞倫說,與剛剛怪異的東西上來......只是迭代的字典(不執行任何操作)改變行爲:

var mc = new MovieClip(); 
var dic = new Dictionary(true); 
dic[mc] = 12; 
addChild(mc); 
removeChild(mc); 
mc = null; 

for (var objeto in dic) {} // <-- try commenting out this line 

addEventListener('enterFrame', f); // I print the contents every frame, to see if 
            // it gets removed after awhile 

function f(evento) 
{ 
    System.gc(); 
    System.gc(); 

    for (var objeto in dic) 
     trace(objeto); 
} 

這樣可以使印刷[對象影片剪輯]每一幀,除非我註釋掉指定的行,它不打印任何內容。

+0

好吧,所以我不認爲這會修復您的引用計數問題...您將該對象設置爲null,在刪除它之後。如果引用計數稍後遞減,如果該對象已經爲空,則可能會導致一些奇怪的行爲...? – 2008-10-17 20:49:01

+0

在你的第二個例子中,你註釋掉的那一行創建了一個你忘記設置爲null的mc(objecto)的新引用。嘗試:for(var objecto in dic){}; objecto = null; – 2008-10-18 12:26:20

+0

就是這樣!謝謝! – Turambar 2008-10-20 15:49:08

回答

1

我認爲問題是時機問題之一。我認爲,當你調用remove child時,引用計數不會在「框架」後面得到更新。 (我認爲這就是發生了什麼)

下面的代碼演示了爲什麼我認爲這是真的。 (我使用的彎曲,但它似乎重現您的問題。)

以下輸出碼:

[object MovieClip] 
here 

如果你直接somefoo()的末尾調用otherfoo,您可以:

[object MovieClip] 
here 
[object MovieClip] 

<?xml version="1.0" encoding="utf-8"?> 
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" mouseDown="somefoo()"> 
<mx:Script> 
    <![CDATA[ 
     import mx.core.UIComponent; 
     private var dic:Dictionary = new Dictionary(true); 
     private var ui:UIComponent = new UIComponent(); 
     private var mc:MovieClip = new MovieClip(); 

     private function somefoo():void { 
      this.addChild(ui); 

      dic[mc] = 12; 
      ui.addChild(mc); 
      ui.removeChild(mc); 
      for (var obj:Object in dic) 
       trace(obj); //this prints [MovieClip] 

      this.removeChild(ui); 

          // callLater causes the function to be called in the _next_ frame. 
      callLater(otherfoo); 
     } 

     private function otherfoo():void 
     { 
      trace("here"); 
      mc = null; 
      System.gc(); 
      System.gc(); 

      for (var obj:Object in dic) 
       trace(obj); //this prints [MovieClip] 

     } 
    ]]> 
</mx:Script> 
</mx:Application> 
0

在你的示例代碼在這裏你永遠將影片剪輯到字典中,但INT 12呢?可能是一個錯字。

如果你想在字典有目前什麼是舞臺上的名單,爲什麼不能我有作爲一個實用程序類而不是聽Event.ADDED_TO_STAGE和Event.REMOVED_FROM_STAGE並修改相應的字典?如果字典從舞臺上移除,它不會自動刪除引用。在這種情況下gc也與此無關。