MovieClip 未从词典中删除

发布于 2024-07-07 06:45:44 字数 1334 浏览 6 评论 0原文

我有一个字典,其中保存影片剪辑的数据,如果我停止使用影片剪辑,我希望对数据进行垃圾收集。 我使用的是弱键参数,它与其他数据完美配合,但是我遇到了问题。

这段代码效果很好:

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

这会保持每帧打印 [object Movieclip] ,除非我注释掉指示的行,它不打印任何内容。

I have a Dictionary where I hold data for movieclips, and I want the data to be garbage collected if I stop using the movieclips. I'm using the weak keys parameters, and it works perfectly with other data, however I've run into a problem.

This code works great:

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

But when I actually use the movieclip, it stops working:

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]

Why does this happen? Is it something I'm doing wrong? Is there a workaround?

Edit: I know that for this specific example I can use delete dic[mc], but of course this is a simplified case. In general, I don't want to manually have to remove the movieclip from the dictionary, but it should be automatic when I don't reference it anymore in the rest of the application.

Edit2: I tried testing what Aaron said, and came up with just weird stuff... just iterating the dictionary (without doing anything) changes the behaviour:

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

This keeps printing [object Movieclip] every frame, unless I comment out the indicated line, where it doesn't print anything.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦开始←不甜 2024-07-14 06:45:44

我认为问题在于时机。 我认为当您调用删除子项时,引用计数直到“框架”稍后才会更新。 (我认为这就是正在发生的事情。)

下面的代码演示了为什么我认为这是真的。 (我正在使用 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>

I believe that the problem is one of timing. I think that when you call remove child, the reference count isn't getting updated until later in the "frame". (I think this is what is happening anyway.)

The code below demonstrates why I think this is true. (I'm using flex, but it appears to reproduce your issue.)

The code below outputs:

[object MovieClip]
here

If you call otherfoo directly at the end of somefoo(), you get:

[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>
空‖城人不在 2024-07-14 06:45:44

在您的示例代码中,您从未将 movieclip 添加到字典中,而是将 int 12 添加到字典中? 可能是一个错字。

如果您希望字典具有当前舞台上内容的列表,为什么不将 i 作为 util 类来侦听 Event.ADDED_TO_STAGE 和 Event.REMOVED_FROM_STAGE 并相应地修改字典? 如果引用从舞台中删除,字典不会自动删除引用。 另外,在这种情况下 gc 与此无关。

In you're example code here you're never adding the movieclip to the dictionary, but the int 12 instead? Probably a typo.

If you want the dictionary to have a list of what's currently on the stage, why not have i as a util class instead that listens to Event.ADDED_TO_STAGE and Event.REMOVED_FROM_STAGE and modify the dictionary accordingly? A dictionary doesn't automatically delete references if they get removed from the stage. Also gc in this case has nothing to do with this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文