32 votes

Comment puis-je obtenir "l'emplacement mémoire" d'une instance dans ActionScript?

FlexBuilder du débogueur va vous montrer la "emplacement de la mémoire" (ou, je ne peux que supposer, quelque chose d'à peu près analogues) de toute la portée de l'instance:

debugger memory location

Mais je voudrais obtenir cette information dans le code (un peu comme Python id de la fonction), donc je pourrais très facilement trace de la façon dont les objets se déplacent à travers le système. Par exemple, je pourrais avoir:

trace("Returning", id(foo));

Puis, quelque part d'autre que je pourrais utiliser:

trace("Using", id(foo));

Pour s'assurer que les deux morceaux de code sont à traiter avec la même instance.

Maintenant, je sais que beaucoup en tant QUE classes implémentent l' IUID interface... Mais il y a aussi un tas de classes qui ne le sont pas (plain old tableaux et les objets, par exemple), donc ça ne résout pas mon problème.

Je me rends compte que je pouvais aussi envelopper des objets dans un ObjectProxy, mais ce serait moins que l'idéal ainsi.

60voto

Diney Bomfim Points 1

Dans vraiment je conseille de ne pas utiliser ce trop... c'est très cher. Adobe besoin de créer une fonction native pour les retourner.

Mais, pour l'instant... essayez ceci:

Vous aurez besoin de causer un explicite de la contrainte pour l'obtenir! Parce que quand vous faites et explicite de la coercition, vous obtenez un message d'Erreur comme ceci:

TypeError: Error #1034: 
De Contrainte de Type échec: impossible de convertir le Principal@1c49d31 de flash.utils.ByteArray.

Notez que dans cette erreur que vous obtenez ce que vous voulez... le @1c49d31. Ce hash est comme un ID dans l'allocation de la mémoire.

J'ai fait beaucoup de tests. Ce hash il suffit de changer lorsque vous appelez un "nouveau" (en C langues est équivalent à [[... alloc] init]) et pour les fonctions statiques et des propriétés statiques, l'affectation se produit un peu différent... de toute façon...

La sauvegarde de la mémoire Flash, le problème est que nous n'avons pas de moyen direct d'obtenir ce hachage sans Erreur.

Mais ce n'est pas un très gros problème. Tout que vous avez besoin est d'utiliser un "try" et "catch" Comme ceci:

essayez
{
ByteArray(anyObjectToKnowItAllocationHash);
}
catch (e:Error)
{
trace(e);
}

Et le tour est joué! Vous obtiendrez la valeur de hachage sans entraîner une Erreur! Après ça je n'ai plus refinated façon... Essayez ceci:

var memoryHash:String;

essayez
{
FakeClass(anyObjectToKnowItAllocationHash);
}
catch (e:Error)
{
 memoryHash = String(e).remplacer(/.*([@|\$].*?) d' .*$/gi, '$1');
}

interne de la classe finale FakeClass { }

Un peu expliquer à ce sujet: Le fakeClass est pour être sûr que cela va générer une Erreur. Le RegularExpression est de capturer le dernier @... qui apparaissent. Parce que les Objets et les Fonctions de générer des messages différents sur cette Erreur. Et le $ est d'attraper les Objets Statiques, de Classe et de Fonctions, car ils n'ont pas un "@" dans son mémoire de hachage et des différentes zones de la mémoire.

Ce petit code fonctionne si bien pour moi! Maintenant, je peux finir quelques grands moteurs que je suis en train de faire ce travail avec la gestion de la mémoire, de la faiblesse des références et des ID basée sur la mémoire.

J'espère que cela peut vous aider.

Bye, et bonne chance, mon ami!

11voto

Ellis Elkins Points 91

La solution de Diney Bomfim a fonctionné comme un charme. J'ai enveloppé cela dans une classe nommée DebugUtils dans une fonction nommée getObjectMemoryHash .

 package
{
    public class DebugUtils
    {
        public static function getObjectMemoryHash(obj:*):String
        {
            var memoryHash:String;

            try
            {
                FakeClass(obj);
            }
            catch (e:Error)
            {
                memoryHash = String(e).replace(/.*([@|\$].*?) to .*$/gi, '$1');
            }

            return memoryHash;
        }
    }
}

internal final class FakeClass { }
 

Ensuite, je pourrais utiliser cette fonction de n'importe où et la suivre, comme ceci:

 trace('myObj', DebugUtils.getObjectMemoryHash(myObj));
 

Merci beaucoup pour cette réponse!

6voto

Branden Hall Points 4225

Du haut de ma tête, la seule façon dont je peux voir cela serait d'utiliser un objet Dictionary (vous voudriez probablement activer les touches faibles pour éviter tout effet secondaire), puis prendre simplement les objets pendant que vous les créez et utilisez-les comme clé d'un compteur ID incrémentiel. Ensuite, vous pouvez simplement voir si deux objets existaient en tant que clés dans le dictionnaire et, dans l'affirmative, comparer les valeurs qui y sont stockées.

5voto

 private static var _uids:Dictionary = new Dictionary(true);
private static var _cter:uint = 1;

public static function getObjectMemoryHash(obj:*):uint {
   var ret:uint = _uids[obj];
   return (ret == 0) ? (_uids[obj] = _cter++) : ret;
}
 

Cela fonctionne bien l'installateur mais il faut un numéro d'identification unique

2voto

Nick Wood Points 260

Jetez un coup d'œil au débogueur Scout d'Adobe - c'est un débogueur beaucoup plus puissant

http://gaming.adobe.com/technologies/scout/

http://www.adobe.com/devnet/scout/articles/adobe-scout-getting-started.html

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X