Подтвердить что ты не робот

Как я могу получить "ячейку памяти" экземпляра в ActionScript?

Отладчик FlexBuilder покажет вам "ячейку памяти" (или, я могу только предположить, что-то примерно аналогичное) любого экземпляра в области видимости:

расположение памяти отладки http://img.skitch.com/20090827-d5nhcnsja3wcgecif3b2dd5ase.png

Но я хотел бы получить эту информацию в коде (вроде функции Python id), поэтому я мог бы очень легко проследить, как объекты перемещаются через систему. Например, я мог бы:

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

Затем в другом месте я мог бы использовать:

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

Чтобы оба бита кода имели дело с одним и тем же экземпляром.

Теперь я знаю, что многие классы AS реализуют интерфейс IUID... Но есть также куча классов, которые не имеют (например, старые старые массивы и объекты), так что это не решило бы мою проблема.

Я понимаю, что я мог бы также обернуть объекты в ObjectProxy, но это было бы не так идеально.

4b9b3361

Ответ 1

В реале я советую вам не использовать это слишком много... это очень дорого. Adobe должна создать собственную функцию, чтобы вернуть это нам.

Но на данный момент... попробуйте следующее:

Вам нужно будет вызвать явное принуждение, чтобы получить его! Потому что, когда вы делаете явное принуждение, вы получаете ошибку вроде этого:

TypeError: Error #1034: 
Type Coercion failed: cannot convert [email protected] to flash.utils.ByteArray.

Обратите внимание, что в этой ошибке вы получаете то, что хотите... @1c49d31. Этот хэш подобен идентификатору в распределении памяти.

Я провел много тестов. Этот хэш просто изменяется, когда вы вызываете "новый" (в языках C эквивалентен [[... alloc] init]), а для статических функций и статических свойств распределение происходит немного иначе... в любом случае...

Возвращаясь к Flash, проблема в том, что у нас нет прямого способа получить этот хэш без ошибки.

Но это не очень большая проблема. Все, что вам нужно, это использовать некоторые "try" и "catch", Вот так:

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 должен быть уверен, что это вызовет ошибку. Регулярное выражение - это захват последнего @..., который появляется. Поскольку объекты и функции генерируют разные сообщения об этой ошибке. И $состоит в том, чтобы поймать статические объекты, класс и функции, поскольку они не имеют "@" в хэш-памяти и разных зонах в памяти.

Этот маленький код работает так хорошо для меня! Теперь я могу закончить несколько отличных движков, которые я делаю с работой с управлением памятью, слабыми ссылками и идентификатором на основе памяти.

Надеюсь, это поможет вам.

Пока, и удачи, мой друг!

Ответ 2

Решение Diney Bomfim работало как шарм. Я завернул это в класс с именем 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));

Большое спасибо за этот ответ!

Ответ 3

В верхней части моей головы единственный способ, которым я могу это сделать, - использовать объект Dictionary (вы, вероятно, захотите включить слабые клавиши, чтобы избежать каких-либо побочных эффектов), а затем просто возьмите объекты, как вы создавать их и использовать их в качестве ключа к счетчику счетчиков с увеличивающимся числом. Затем вы можете просто посмотреть, существуют ли два объекта в качестве ключей в словаре и если они сравнивают хранящиеся там значения.

Ответ 4

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

Это работает нормально, но требуется уникальный идентификационный номер

Ответ 6

AFAIK нет способа получить значение, которое отладчик показывает вам во время выполнения.

Общий снимок в темноте, но я думаю, вы можете использовать сравнение ===, чтобы определить, являются ли два объекта одним и тем же объектом (в отличие от ==, который сравнивает значения объектов). Но я мог бы ошибаться.