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

此代码效果很好:

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,但是当我不再在应用程序的其余部分引用它时它应该是自动的。

Edit2:我尝试过测试Aaron所说的内容,并想出了一些奇怪的东西......只是迭代字典(不做任何事情)改变行为:

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

这样可以保持每帧打印[对象动画片段],除非我注释掉指定的行,它不打印任何内容。

有帮助吗?

解决方案

我认为问题在于时机问题。我认为当你调用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>

其他提示

在你的示例代码中,你永远不会将movieclip添加到字典中,而是将int 12添加到字典中?可能是一个错字。

如果你想让字典列出当前在舞台上的内容,为什么不将i作为util类而不是监听Event.ADDED_TO_STAGE和Event.REMOVED_FROM_STAGE并相应地修改字典呢?如果从阶段中删除引用,则字典不会自动删除引用。在这种情况下,gc也与此无关。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top