2009-08-27 12 views
30

FlexBuilder pokaże Ci „miejsce w pamięci” (lub, mogę tylko przypuszczać, co z grubsza analagous) dowolnego przykład w-zakresie:Jak mogę uzyskać "lokalizację pamięci" instancji w ActionScripcie? debugger

debugger memory location http://img.skitch.com/20090827-d5nhcnsja3wcgecif3b2dd5ase.png

Ale chciałbym, aby uzyskać te informacje w kod (trochę jak funkcja Pythona id), dzięki czemu mogłem bardzo łatwo prześledzić, jak obiekty przemieszczają się przez system. Na przykład może mam:

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

Potem gdzieś indziej mógłbym użyć:

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

Aby upewnić się oba fragmenty kodu do czynienia z tej samej instancji.

Teraz wiem, że wiele klas AS implementuje interfejs IUID ... Ale istnieje również grupa klas, które nie działają (zwykłe stare tablice i obiekty, na przykład), więc to nie rozwiązałoby mojego problemu .

Zdaję sobie sprawę, że mogłem również owijać obiekty w ObjectProxy, ale to też byłoby mniej niż idealne.

+1

ci może chcesz rzucić okiem na to: http://stackoverflow.com/questions/1151627/object-reference-as-string/1153833#1153833, który q uite jaki branden zaproponował ... :) – back2dos

+0

Ah, to wygląda dobrze - dzięki! –

Odpowiedz

59

Naprawdę radzę nie używać tego zbyt wiele ... jest bardzo drogi. Adobe musi utworzyć natywną funkcję, aby zwrócić to nam.

Ale teraz ... spróbuj tego:

Musisz spowodować wyraźny przymus je zdobyć! Bo kiedy robisz i wyraźny przymus pojawi się błąd jak poniżej:

 
TypeError: Error #1034: 
Type Coercion failed: cannot convert [email protected] to flash.utils.ByteArray. 

pamiętać, że w tym błędzie można dostać to, co chcesz ... do @ 1c49d31. To hash jest jak identyfikator w alokacji pamięci.

Zrobiłem wiele testów. Ten skrót zmienia się po wywołaniu "nowego" (w językach C jest równoważny z [[... alloc] init]), a dla funkcji statycznych i właściwości statycznych alokacja występuje trochę inaczej ... tak czy inaczej ...

Kopię zapasową Flasha polega na tym, że nie mamy bezpośredniego sposobu na uzyskanie tego skrótu bez błędu.

Ale to nie jest duży problem. Wszystko, co potrzebne jest, aby korzystać z niektórych „try” i „złapać” tak:

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

i voila! Otrzymasz hash bez wyniku w błędzie! Potem zrobiłem więcej refinated sposób ... Spróbuj tego:

var memoryHash:String; 

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

internal final class FakeClass { } 

Trochę wyjaśnienia na ten temat: fakeClass jest, aby upewnić się o tym wygeneruje błąd. Funkcja RegularExpression służy do przechwytywania ostatnich @ ..., które się pojawiają. Ponieważ Obiekty i funkcje generują różne komunikaty o tym błędzie. A $ to złapanie Static Objects, Class i Functions, ponieważ nie mają one "@" w haszowaniu pamięci i różnych stref w pamięci.

Ten mały kod działa tak dobrze dla mnie! Teraz mogę sfinalizować kilka świetnych silników, które wykonuję w tej pracy z zarządzaniem pamięcią, słabymi referencjami i identyfikatorem opartym na pamięci.

Mam nadzieję, że to może ci pomóc.

Do widzenia, i powodzenia, przyjacielu!

+0

hahahha Diney, to jest genialne. Dobra robota. –

+0

Haha, to z pewnością szalony hack! –

+0

Kudos, który jest niesamowity! –

6

Z góry mojej głowy jedyny sposób, w jaki mogę to zobaczyć, to użycie obiektu Dictionary (prawdopodobnie chciałbyś włączyć słabe klawisze, aby uniknąć efektów ubocznych), a następnie po prostu wziąć obiekty jako tworzysz je i używasz ich jako klucza do zwiększającego się licznika ID. Wtedy możesz po prostu sprawdzić, czy dwa obiekty istnieją jako klucze w Słowniku, a jeśli tak, to porównaj wartości tam zapisane.

+0

ah, tak - to nie jest zły pomysł. Dzięki! –

1

AFAIK nie ma sposobu, aby uzyskać wartość, którą debugger pokazuje w czasie wykonywania.

Całkowite ujęcie w ciemności, ale myślę, że można użyć porównania ===, aby określić, czy dwa obiekty są tym samym obiektem (w przeciwieństwie do ==, który porównuje wartości obiektów). Ale mógłbym być całkowicie w błędzie.

+0

To prawda, że ​​"===" porówna tożsamość dwóch obiektów ... Ale to niewiele mi pomoże (chyba że zachowam odniesienie do każdego obiektu, to ...) –

+0

@David: Jeśli nie masz odniesienie do każdego obiektu, niż w jaki sposób uzyskujesz dostęp do swoich obiektów? Jeśli nie masz odniesień do twoich obiektów, zostaną zebrane śmieci. – Luke

+0

Myślę, że to nie było jasne - będą odniesienia do każdej instancji * gdzieś *, ale nie będzie "jednego centralnego repozytorium wszystkich moich instancji". –

11

Rozwiązanie Diney Bomfim działało jak czar. Zawinęłem to w klasie o nazwie DebugUtils w funkcji o nazwie 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 { } 

Wtedy mógłbym użyć tej funkcji z dowolnego miejsca i je prześledzić, jak w przykładzie:

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

Dziękuję za odpowiedź!

+3

jeśli usuniesz funkcję z klasy, usuniesz statyczny i zmieni nazwę pliku getObjectMemoryHash.as, wtedy będziesz mógł po prostu użyć go bezpośrednio, podobnie jak' getTimer() ' – divillysausages

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

ta działa poprawnie instalator ale ma unikalny numer identyfikacyjny

Powiązane problemy