2008-10-17 66 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也与此无关。