代码之家  ›  专栏  ›  技术社区  ›  Fabian Steeg

movieclip未从字典中删除

  •  2
  • Fabian Steeg  · 技术社区  · 16 年前

    我有一本字典,我在其中保存movieclips的数据,如果我停止使用movieclips,我希望这些数据被垃圾收集。我使用的是弱键参数,它与其他数据完美配合,但是我遇到了一个问题。

    此代码非常有效:

    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
    

    但当我实际使用movieclip时,它就停止工作了:

    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] 当然,这是一个简化的案例。一般来说,我不想手动从字典中删除movieclip,但是当我在应用程序的其余部分不再引用它时,它应该是自动的。

    伊迪丝2:我试着测试亚伦说的话,发现了一些奇怪的东西……只需迭代字典(不做任何事情)就可以改变行为:

    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);
    }
    

    这会一直打印每一帧的[对象movieclip],除非我注释掉指示行,它不打印任何内容。

    2 回复  |  直到 16 年前
        1
  •  1
  •   Aaron H.    16 年前

    我认为问题在于时机。我认为,当您调用remove child时,引用计数直到稍后在“frame”中才得到更新。(我想这就是发生的事情。)

    下面的代码演示了为什么我认为这是真的。(我正在使用flex,但它似乎复制了您的问题。)

    下面的代码输出:

    [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>
    
        2
  •  0
  •   Antti    16 年前

    在这里的示例代码中,您从不将movieclip添加到字典中,而是将int 12添加到字典中?可能是打字错误。

    如果您希望字典有一个当前在阶段上的列表,为什么不让我作为一个实用程序类来代替它来侦听event.added-to-stage和event.removed-from-stage并相应地修改字典?如果引用从阶段中删除,字典不会自动删除引用。在这种情况下,GC也与此无关。