簡體   English   中英

如何在ActionScript中獲取實例的“內存位置”?

[英]How can I get an instance's “memory location” in ActionScript?

FlexBuilder的調試器將向您顯示任何范圍內實例的“內存位置”(或者,我只能假設,大致類似):

調試器內存位置

但我想在代碼中獲取這些信息(有點像Python的id函數),因此我可以很容易地跟蹤對象如何在系統中移動。 例如,我可能有:

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

然后我可以使用的其他地方:

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

確保兩個代碼都處理相同的實例。

現在,我知道許多AS類實現了IUID接口......但是也有一些類沒有(例如普通的舊數組和對象),所以這不能解決我的問題。

我意識到我也可以在ObjectProxy包裝對象,但這也不太理想。

真的,我建議你不要使用太多......這是非常昂貴的。 Adobe需要創建一個本機函數來將其返回給我們。

但是,現在......試試這個:

你需要明確的強制來獲得它! 因為當你制作並明確強制時,你得到一個像這樣的錯誤:

TypeError: Error #1034: 
Type Coercion failed: cannot convert Main@1c49d31 to flash.utils.ByteArray.

請注意,在此錯誤中,您可以得到您想要的... @ 1c49d31。 此哈希就像內存分配中的ID。

我做了很多測試。 當你調用“new”時這個哈希就會改變(在C語言中相當於[[... alloc] init]),對於靜態函數和靜態屬性,分配發生了一點點不同......無論如何......

回到Flash,問題是我們沒有直接的方法來獲取沒有錯誤的哈希。

但這不是一個很大的問題。 你需要的只是使用一些“嘗試”和“捕獲”像這樣:

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確定會產生錯誤。 RegularExpression用於捕獲出現的最后一個@ .... 因為對象和函數在此錯誤上生成不同的消息。 而且$是為了捕獲靜態對象,類和函數,因為它們的內存哈希中沒有“@”,而內存中的區域也不同。

這個小代碼對我來說很好用! 現在我可以完成一些偉大的引擎,我正在使用內存管理,弱引用和基於內存的ID。

我希望這可以幫到你。

再見,祝你好運,我的朋友!

Diney Bomfim的解決方案就像一個魅力。 我將它包裝在一個名為DebugUtils的類中, DebugUtils位於名為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 { }

然后我可以從任何地方使用此函數並跟蹤它,如下所示:

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

非常感謝這個答案!

在我的腦海中,我可以看到將其拉下來的唯一方法是使用Dictionary對象(您可能希望啟用弱鍵以避免任何副作用)然后只需在創建它們時獲取對象將它們用作遞增ID計數器的鍵。 然后你可以簡單地查看兩個對象是否作為字典中的鍵存在,如果是,則比較存儲在那里的值。

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

這是一個很好的安裝程序,但它需要唯一的標識號

AFAIK無法獲得調試器在運行時顯示的值。

在黑暗中完全拍攝但我認為您可以使用===比較來確定兩個對象是否是同一個對象(與==比較對象的值相反)。 但我可能完全錯了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM