AS3: Как глубоко копировать объект

У меня есть объект, который мне нужно скопировать в мои данные SharedObject. Проблема в том, что свойство data общего объекта доступно только для чтения, поэтому я не могу клонировать свой "исходный" объект и назначить его данным общего объекта, мне нужно сделать их копию следующим образом:

var so: SharedObject = SharedObject.getLocal("appData");
copyObject(sourceObj, so.data);
so.flush();

и метод копирования:

public static function copyObject(sourceObject:Object, destinationObject:Object):void{
    // this would be the code that i need
}

Также имейте в виду, что мой объект имеет свойства, которые являются объектами, поэтому он имеет внутри n уровней объектов. Вот почему я не могу просто сделать для каждого и назначить все свойства на первом уровне, поэтому мне нужно сделать ГЛУБОКУЮ копию, возможно, рекурсивную. Я часами пытался сделать этот метод copyObject безуспешно. Также я искал в интернете, но не нашел ни одной подходящей мне копии объекта.

Может кто-нибудь помочь мне с этим методом? Я действительно оценил бы это!

Спасибо за помощь!

3 ответа

Для сложных объектов я бы использовал RegisterClassAlias:

import flash.net.registerClassAlias;
registerClassAlias("YourClassName", YourClassName);
var so:SharedObject = SharedObject.getLocal("objectName");
so.data.yourData = YourClassName.instance;
so.flush();

Для простого типа объекта с глубоким уровнем простых данных (примитивы, включая массивы) я бы просто использовал JSON.stringify() и JSON.parse() при считывании данных.

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

Эта функция возьмет объект и превратит его в строку

public static function serializeToString(value:Object):String{
                        if(value==null){
                            throw new Error("null isn't a legal serialization candidate");
                        }

                        var bytes:ByteArray = new ByteArray();
                        bytes.writeObject(value);
                        bytes.position = 0;
                        return Base64.encodeByteArray(bytes);
}

Этот вернет ваш объект из строки.

public static function readObjectFromStringBytes(value:String):Object{

              var result:ByteArray =   Base64.decodeToByteArray( value) as ByteArray;
                  result.position = 0;
                  return result.readObject();

                } 

Класс кодирования Base 64 вы можете найти здесь https://github.com/juancgarcia/screenshotify/blob/master/Downloadify-652377f/src/com/dynamicflash/util/Base64.as.

Вам необходимо реализовать IExternalizable на всех объектах, которые вы хотите хранить таким образом. Реализация включает в себя создание writeExternal метод вызывается против ByteArray, когда вы делаете writeObject(), а также readExternal методы, которые вызываются для вновь созданного экземпляра, поэтому ваш класс должен записать необходимые метаданные, чтобы ваш объект был глубоко клонирован, включая запись объектов свойств.

Руководство поIExternalizable

И на заметку, вы не должны хранить один объект во всем so.dataлучше назначить поле в so.data и напишите туда свою копию объекта.

Другие вопросы по тегам