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

你说的曾经没有我的故事 提交于 2019-11-27 12:38:48
Diney Bomfim

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!

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!

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.

Lakshmi Narayana
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

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!