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
и напишите туда свою копию объекта.