31


8

FlexBuilderのデバッガは、スコープ内インスタンスの「メモリの場所」(または、おおよそ類似したものしか想定できない)を表示します。

image:https://i.stack.imgur.com/uPAdn.png [デバッガメモリの場所]

しかし、私はこの情報をコード(Pythonの `id`関数のようなもの)で取得したいので、オブジェクトがどのようにシステムを通過するのかを非常に簡単に追跡できました。 たとえば、次のようになります。

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

それから他のどこかで私は使うことができます:

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

コードの両方のビットが同じインスタンスを扱っていることを確認するため。

今、私は多くのASクラスが `IUID`インターフェースを実装していることを知っています…​ しかし、そうでないクラスもたくさんあります(例えば、普通の古い配列やオブジェクト)、それで私の問題を解決することはできません。

私はオブジェクトを `ObjectProxy`でラップすることもできますが、それも理想とは言えないでしょう。

6 Answer


59


本当に私はあなたにこれを使いすぎないように忠告します…​ それはとても高価です。 アドビはこれを返すためにネイティブ関数を作成する必要があります。

しかし、今のところ…​ これを試して:

あなたはそれを得るために明示的な強制を引き起こす必要があるでしょう! なぜなら、あなたが明示的な強制をすると、次のようなエラーになるからです。

TypeError:エラー#1034:型強制に失敗しました:Main @ 1c49d31をflash.utils.ByteArrayに変換できません

このエラーであなたが望むものを得ることに注意してください…​ @ 1c49d31 このハッシュは、メモリ割り当てにおけるIDのようなものです。

私はたくさんのテストをしました。 このハッシュは、 "new"を呼び出すと変わるだけです(C言語では[[…​ そして、静的関数と静的プロパティの場合、割り当ては少し異なります。 とにかく…​

Flashに戻ると、問題は、エラーなしにこのハッシュを取得する直接的な方法がないことです。

しかし、これは本当に大きな問題ではありません。 あなたが必要とするのは、次のようにいくつかの "try"と "catch"を使うことです。

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

そして、やあ! あなたはエラーにならずにハッシュを得るでしょう! この後、私はもっと洗練されたやり方をしました…​ これを試して:

var memoryHash:String;

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

internal final class FakeClass { }

これについて少し説明します。fakeClassは、これについて確実にErrorを生成することです。 RegularExpressionは最後の@をキャプチャすることです…​ それが現れます。 オブジェクトと関数はこのエラーに対して異なるメッセージを生成するからです。 そして$はスタティックオブジェクト、クラス、関数をキャッチするためのものです。なぜならそれらはメモリハッシュに "@"がなく、メモリ内に異なるゾーンがないからです。

この小さなコードは私にはとてもうまくいきます! これで、メモリ管理、弱い参照、およびメモリに基づくIDを使用して動作させることができた優れたエンジンをいくつか完成させることができます。

これがお役に立てば幸いです。

さようなら、そして幸運を祈ります。


11


Diney Bomfimのソリューションは、魅力的なものでした。 私はこれを DebugUtils`という名前のクラスと getObjectMemoryHash`という名前の関数にラップしました。

package {public class DebugUtils {public static function getObjectMemoryHash(obj:*):文字列{var memoryHash:文字列。

{FakeClass(obj);をお試しください。 catch(e:エラー){memoryHash =文字列(e).replace(/.*([@ | \ $]。*?)to。* $ / gi、 '$ 1'); }

memoryHashを返します。 }}}

内部最終クラスFakeClass {}

それから私はどこからでもこの関数を使ってそれをトレースすることができます。

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

この回答をどうもありがとう!


6


私の頭の上でこれをやってのけることができる唯一の方法はDictionaryオブジェクトを使用することです(おそらくあなたは弱いキーを有効にして副作用を避けることを望んでいるでしょう)。インクリメントIDカウンタへのキーとしてそれらを使用してください。 次に、2つのオブジェクトが辞書にキーとして存在しているかどうかを確認し、存在する場合はそこに格納されている値を比較します。


5


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

パブリック静的関数getObjectMemoryHash(obj:*):uint {var ret:uint = _uids [obj];戻る(ret == 0) (_uids [obj] = _cter):ret; }

これはすばらしいインストーラを動かしています、しかしそれはユニークな識別番号を取ります


2


AdobeのScout Debuggerを見てください。はるかに強力なデバッガーです。


1


私の知る限りでは、デバッガが実行時に表示している値に到達する方法はありません。

暗闇の中でのトータルショットですが、2つのオブジェクトが同じオブジェクトであるかどうかを判断するために===比較を使用できると思います(==はオブジェクトの値を比較します)。 しかし、私はそれについて全く間違っている可能性があります。