Question

J'ai un dictionnaire dans lequel je tiens les données de MovieClips, et je veux que les données soient collectées si je cesse d'utiliser les MovieClips. J'utilise les paramètres de clés faibles et cela fonctionne parfaitement avec d'autres données, mais j'ai un problème.

Ce code fonctionne très bien:

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

Mais lorsque j'utilise le MovieClip, il ne fonctionne plus:

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]

Pourquoi cela se produit-il? Est-ce quelque chose que je fais mal? Y a-t-il une solution de contournement?

Éditer: Je sais que pour cet exemple spécifique, je peux utiliser delete dic [mc] , mais bien entendu, il s’agit d’un cas simplifié. En général, je ne souhaite pas supprimer manuellement le MovieClip du dictionnaire, mais il devrait être automatique lorsque je ne le référence plus dans le reste de l'application.

Edit2: J'ai essayé de tester ce qu'Aaron avait dit et je suis arrivé avec des trucs bizarres ... il suffit de réitérer le dictionnaire (sans rien faire) change le comportement:

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

Ceci continue à imprimer [objet Movieclip] chaque image, à moins que je ne commente la ligne indiquée, où elle n’imprime rien.

Était-ce utile?

La solution

Je pense que le problème réside dans le choix du moment. Je pense que lorsque vous appelez remove child, le décompte de références ne sera mis à jour que plus tard dans le "cadre". (Je pense que c'est ce qui se passe de toute façon.)

Le code ci-dessous montre pourquoi je pense que cela est vrai. (J'utilise flex, mais cela semble reproduire votre problème.)

Le code ci-dessous renvoie:

[object MovieClip]
here

Si vous appelez otherfoo directement à la fin de somefoo (), vous obtenez:

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

Autres conseils

Dans votre exemple de code, vous n’ajoutez jamais le MovieClip au dictionnaire, mais plutôt l’int 12? Probablement une faute de frappe.

Si vous voulez que le dictionnaire ait une liste de ce qui est actuellement sur la scène, pourquoi ne pas avoir i comme classe util qui écoute Event.ADDED_TO_STAGE et Event.REMOVED_FROM_STAGE et modifier le dictionnaire en conséquence? Un dictionnaire ne supprime pas automatiquement les références si elles sont supprimées de la scène. Aussi, dans ce cas, gc n’a rien à voir avec cela.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top