Domanda

Ho un dizionario in cui conservo i dati per i Movie Clip e desidero che i dati vengano raccolti in modo inutile se smetto di utilizzare i Movie Clip. Sto usando i parametri dei tasti deboli e funziona perfettamente con altri dati, tuttavia ho riscontrato un problema.

Questo codice funziona alla grande:

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

Ma quando uso effettivamente il Movie Clip, smette di funzionare:

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]

Perché succede? È qualcosa che sto facendo di sbagliato? C'è una soluzione alternativa?

Modifica: so che per questo esempio specifico posso usare delete dic [mc] , ma ovviamente questo è un caso semplificato. In generale, non voglio rimuovere manualmente il Movie Clip dal dizionario, ma dovrebbe essere automatico quando non lo faccio più riferimento nel resto dell'applicazione.

Modifica2: ho provato a testare ciò che Aaron ha detto e ho escogitato solo cose strane ... solo iterando il dizionario (senza fare nulla) cambia il 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);
}

Questo continua a stampare [oggetto Movieclip] ogni fotogramma, a meno che non scriva la riga indicata, dove non stampa nulla.

È stato utile?

Soluzione

Credo che il problema sia legato al tempismo. Penso che quando chiami remove child, il conteggio dei riferimenti non viene aggiornato fino a dopo nel "frame". (Penso che sia quello che sta succedendo comunque.)

Il codice seguente mostra perché penso che sia vero. (Sto usando Flex, ma sembra riprodurre il tuo problema.)

Il codice seguente mostra:

[object MovieClip]
here

Se si chiama otherfoo direttamente alla fine di somefoo (), si ottiene:

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

Altri suggerimenti

Nel tuo esempio di codice qui non aggiungi mai il Movie Clip al dizionario, ma invece int 12? Probabilmente un errore di battitura.

Se vuoi che il dizionario abbia un elenco di ciò che è attualmente sullo stage, perché non ho io come classe util invece che ascolta Event.ADDED_TO_STAGE ed Event.REMOVED_FROM_STAGE e modifica il dizionario di conseguenza? Un dizionario non elimina automaticamente i riferimenti se vengono rimossi dallo stage. Anche gc in questo caso non ha nulla a che fare con questo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top