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

2019-01-11 02:54发布

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.

6条回答
啃猪蹄的小仙女
2楼-- · 2019-01-11 03:17

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.

查看更多
ら.Afraid
3楼-- · 2019-01-11 03:20

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!

查看更多
姐就是有狂的资本
4楼-- · 2019-01-11 03:26

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!

查看更多
smile是对你的礼貌
5楼-- · 2019-01-11 03:26
The star\"
6楼-- · 2019-01-11 03:27
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

查看更多
孤傲高冷的网名
7楼-- · 2019-01-11 03:40

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.

查看更多
登录 后发表回答