如何获取实例的“内存位置”在动作脚本中?

发布于 2024-08-03 08:10:47 字数 504 浏览 2 评论 0原文

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

“调试器内存位置”

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

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

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

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

确保这两个代码位都处理同一个实例。

现在,我知道许多 AS 类实现了 IUID 接口...但是也有很多类没有实现(例如,普通的旧数组和对象),所以这不会解决我的问题。

我意识到我也可以将对象包装在 ObjectProxy 中,但这也不太理想。

FlexBuilder's debugger will show you the "memory location" (or, I can only assume, something roughly analogous) of any in-scope instance:

debugger memory location

But I'd like to get this information in code (sort of like Python's id function), so I could very easily trace how objects move through out the system. For example, I might have:

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

Then somewhere else I could use:

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

To make sure both bits of code are dealing with the same instance.

Now, I know that many AS classes implement the IUID interface... But there are also a bunch of classes which don't (plain old arrays and objects, for example), so that wouldn't solve my problem.

I realize that I could also wrap objects in an ObjectProxy, but that would be less than ideal as well.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

雪化雨蝶 2024-08-10 08:10:47

实际上我建议你不要太多使用这个......它非常昂贵。 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 是为了确保这会产生一个错误。
正则表达式是捕获最后出现的@...。因为对象和函数在此错误上生成不同的消息。 $ 是捕获静态对象、类和函数,因为它们的内存哈希中没有“@”,并且内存中存在不同的区域。

这个小代码对我来说效果很好!现在我可以完成一些很棒的引擎,它们可以与内存管理、弱引用和基于内存的 ID 一起使用。

我希望这可以帮助你。

再见,祝你好运,我的朋友!

In realy I advise to you don't to use this too much... it is very expensive. Adobe need to create a native function to return this to us.

But, for now... try this:

You will need to cause a explicit coercion to get it!
Because when you make and explicit coercion you get an Error like this:

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

Note that in this error you get what you want... the @1c49d31. This hash is like an ID in the memory allocation.

I did a lot of tests. This hash just change when you call a "new" (in C languages is equivalent to [[... alloc] init]) and for static functions and static properties, the allocation occurs a little different... anyway...

Backing to Flash, the problem is we don't have a direct way to get this hash without an Error.

But this is not a realy big problem. All that you need is to use some "try" and "catch"
Like this:

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

And voila!
You will get the hash without result in an Error!
After this I did a more refinated way... Try this:

var memoryHash:String;

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

internal final class FakeClass { }

A little explain about this:
The fakeClass is to be sure about this will generate an Error.
The RegularExpression is to capture the last @... that appear. Because Objects and Functions generate different messages on this Error. And the $ is to catch the Static Objects, Class and Functions, bacause they don't have an "@" in its memory hash and different zones in memory.

This little code works so fine to me! Now i can finish some great engines that i'm making that work with memory management, weak references and ID based on memory.

I hope this can help you.

Bye, and good luck, my friend!

水中月 2024-08-10 08:10:47

迪尼·博姆菲姆的解决方案非常有效。我将其包装在名为 getObjectMemoryHash 的函数中名为 DebugUtils 的类中。

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

非常感谢这个答案!

Diney Bomfim's solution worked like a charm. I wrapped this in a class named DebugUtils in a function named 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 { }

Then I could use this function from anywhere and trace it, like so:

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

Thanks so much for this answer!

可可 2024-08-10 08:10:47

在我的脑海中,我能想到的唯一方法是使用 Dictionary 对象(您可能希望启用弱键以避免任何副作用),然后在创建对象时获取它们并将它们用作递增 ID 计数器的密钥。然后,您可以简单地查看两个对象是否作为字典中的键存在,如果存在,则比较存储在那里的值。

Off the top of my head the only way I can see to pull this off would be to use a Dictionary object (you'd probably want to enable weak keys to avoid any side effects) and then just take the objects as you create them and use them as a key to an incrementing ID counter. Then you could simply look to see if two objects existed as a keys in the Dictionary and if so compare the values stored there.

橘虞初梦 2024-08-10 08:10:47
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;
}

安装程序运行良好,但需要唯一的标识号

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

This is working fine installer but it takes unique identification number

陈年往事 2024-08-10 08:10:47

AFAIK 无法获取调试器在运行时显示的值。

完全在黑暗中拍摄,但我认为您可以使用 === 比较来确定两个对象是否是同一对象(与比较对象值的 == 相反)。但我可能完全错了。

AFAIK there is no way to get to the value that the debugger shows you at runtime.

Total shot in the dark but I think you can use the === comparison to determine if two objects are the same object (in contrast to == that compares the values of the objects). But I could be totally wrong on that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文