Pergunta

Eu tenho um dicionário onde eu armazenar dados para movieclips, e eu quero que os dados sejam coletados como lixo se eu parar de usar os movieclips. Estou usando os parâmetros chaves fracas, e ele funciona perfeitamente com outros dados, no entanto eu correr em um problema.

Este código funciona muito bem:

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

Mas quando eu realmente usar o movieclip, ele pára de funcionar:

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]

Por que isso acontece? É algo que eu estou fazendo errado? Existe uma solução?

Edit: Eu sei que para este exemplo específico que eu possa usar delete dic[mc], mas é claro que este é um caso simplificado. Em geral, eu não quero ter manualmente para remover o clipe de filme a partir do dicionário, mas deve ser automática quando eu não fazer referência a ela mais no resto da aplicação.

Edit2: Eu tentei testar o que Aaron disse, e veio com coisas apenas estranho ... apenas repetindo o dicionário (sem fazer nada) altera o comportamento:

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

Isso mantém a impressão [objeto MovieClip] cada quadro, a menos que eu comente a linha indicada, onde não imprimir nada.

Foi útil?

Solução

Eu acredito que o problema é de timing. Eu acho que quando você chamar criança de remoção, a contagem de referência não está sendo atualizado até mais tarde no "frame". (Acho que é isso que está a acontecer de qualquer maneira.)

O código abaixo demonstra porque eu acho que isso é verdade. (Estou usando Flex, mas parece reproduzir o problema.)

O código abaixo saídas:

[object MovieClip]
here

Se você chamar otherfoo diretamente no final do somefoo (), você obtém:

[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>

Outras dicas

Em que você está exemplo de código aqui você nunca está adicionando o movieclip com o dicionário, mas o int 12 em vez disso? Provavelmente um erro de digitação.

Se você quiser o dicionário para ter uma lista do que está atualmente no palco, porque não têm i como um util classe em vez que ouve Event.ADDED_TO_STAGE e Event.REMOVED_FROM_STAGE e modificar o dicionário de conformidade? Um dicionário não exclui automaticamente as referências se eles se retirado do palco. Também gc neste caso não tem nada a ver com isso.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top