apache-flex 如何在ActionScript中取得实体的“内存位置”?

p1tboqfb  于 2022-11-01  发布在  Apache
关注(0)|答案(6)|浏览(142)

FlexBuilder的调试器将向您显示任何范围内示例的“内存位置”(或者,我只能假设,大致类似的位置):

但是我希望用代码来获取这些信息(有点像Python的id函数),这样我就可以很容易地跟踪对象是如何在系统中移动的。

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

那我可以去别的地方:

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

以确保这两段代码处理的是同一个示例。
现在,我知道许多AS类实现了IUID接口......但也有一堆类没有实现(例如,普通的旧数组和对象),所以这不能解决我的问题。
我意识到我也可以将对象 Package 在ObjectProxy中,但这也不太理想。

t5fffqht

t5fffqht1#

在现实中,我建议你不要使用这个太多...它是非常昂贵的。Adobe需要创建一个本地函数返回给我们。
不过,现在......试试这个:
你需要进行显式强制才能得到它!因为当你进行显式强制时,你会得到一个如下的错误:

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

请注意,在这个错误中,您会得到您想要的...@1c49d31。这个杂凑就像内存配置中的ID。
我做了很多测试。当你调用一个“new”(在C语言中等价于[[... alloc] init])时,这个哈希值会发生变化。对于静态函数和静态属性,分配会发生一点不同...总之...
回到闪存,问题是我们没有一个直接的方法来获得这个哈希值而不出现错误。
但这并不是一个真正的大问题。你所需要的只是使用一些“尝试”和“捕捉”,就像这样:

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工作。
我希望这能对你有所帮助。
再见,祝你好运,我的朋友!

wa7juj8i

wa7juj8i2#

Diney Bomfim的解决方案非常有效,我将其封装在一个名为getObjectMemoryHash的类和一个名为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));

非常感谢您的回答!

oprakyz7

oprakyz73#

在我看来,实现这一点的唯一方法是使用一个Dictionary对象(您可能希望启用弱键以避免任何副作用),然后在创建对象时将其作为递增ID计数器的键。然后,您可以简单地查看是否有两个对象作为Dictionary中的键存在,如果存在,则比较存储在那里的值。

ldfqzlk8

ldfqzlk84#

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

这是工作正常安装程序,但它需要唯一的标识号

bejyjqdl

bejyjqdl6#

AFAIK没有办法获得调试器在运行时显示的值。
完全是瞎猜,但我认为你可以用===比较来确定两个对象是否是同一个对象(与比较对象值的==相反),但我可能完全错了。

相关问题