Copying Objects Using ByteArray
- Transfer
Copy simple objects
Most often, ByteArray is used to copy objects. AMF serializer and deserializer (I do not like these words, but did not find a suitable translation) is available through the ByteArray API . To duplicate objects using ByteArray, we will use the writeObject and readObject methods :
// Создаём пустой ByteArray
var stream:ByteArray = new ByteArray();
// Создаём объект
var parameters:Object = { age : 25, name : "Bob" };
// «Переводим» объект в формат AMF и сохраняем его в ByteArray
stream.writeObject( parameters );
// Сбрасываем позицию
stream.position = 0;
// Считываем объект
var objectCopy:Object = stream.readObject();Based on this code, you can create a function that we can use to copy objects:
function copyObject(objectToCopy:*):*
{
var stream:ByteArray = new ByteArray();
stream.writeObject( objectToCopy );
stream.position = 0;
return stream.readObject();
}To make sure that we actually created a separate copy of the object, we can modify the properties of the original object:
// Создаём объект
var parameters:Object = { age : 25, name : "Bob" };
var parametersCopy:Object = copyObject ( parameters );
parameters.nom = "Stevie";
/* outputs :
name : Bob
age : 25
*/
for ( var p:String in parametersCopy )
{
trace( p, " : ", parametersCopy[p] );
}
function copyObject ( objectToCopy:* ):*
{
var stream:ByteArray = new ByteArray();
stream.writeObject( objectToCopy );
stream.position = 0;
return stream.readObject();
}Below we will learn how to save and restore more complex data types using ByteArray .
Copy custom classes
The code described earlier will not work for custom classes that you can use in your application. Let's analyze a very simple example, let's say you need to use objects of the User class :
package
{
public class User
{
private var _firstName:String;
private var _lastName:String;
public function set firstName (firstName:String):void
{
_firstName = firstName;
}
public function set lastName (lastName:String):void
{
_lastName = lastName;
}
public function get firstName ():String
{
return _firstName;
}
public function get lastName ():String
{
return _lastName;
}
}
}You may need to save an object of the User class on the server as binary data or locally in SharedObject . If you try to save an object of the User class in ByteArray and retrieve it, then when reading, Flash Player will check if the User type has been registered before, if not, then this object will be “parsed” like a regular object:
// Создаём экземпляр класса User
var myUser:User = new User ();
// Устанавливаем свойства
myUser.firstName = "Stevie";
myUser.lastName = "Wonder";
// outputs :[object User]
trace ( myUser );
// Создаём ByteArray для сохранения экземпляра
var bytes:ByteArray = new ByteArray();
// Сохраняем экземпляр
bytes.writeObject ( myUser );
// Сбрасываем позицию
bytes.position = 0;
// outputs : false
trace ( bytes.readObject() is User );You can use the registerClassAlias method to register a User type in Flash Player . After that, objects of the User class can be “parsed” using ByteArray .
// Создаём экземпляр класса User
var myUser:User = new User ();
// Устанавливаем свойства
myUser.firstName = "Stevie";
myUser.lastName = "Wonder";
// outputs :[object User]
trace ( myUser );
// Регистрируем тип User для «разбора»
registerClassAlias ( "userTypeAlias", User );
// Создаём ByteArray для сохранения экземпляра
var bytes:ByteArray = new ByteArray();
// Сохраняем экземпляр
bytes.writeObject ( myUser );
// Сбрасываем позицию
bytes.position = 0;
// При «разборе» сохраненённого объекта, автоматически будет использоваться нужный тип
var storedUser:User = bytes.readObject() as User;
// outputs : true
trace ( storedUser is User );
// outputs : Stevie Wonder
trace ( storedUser.firstName, storedUser.lastName );Using this technique, we can save and restore instances of any custom classes. As you can see, now we are working with a copy of the user class object:
storedUser.firstName = "Bobby";
storedUser.lastName = "Womack";
// outputs : Stevie Wonder
trace ( myUser.firstName, myUser.lastName );
// outputs : Bobby Womack
trace ( storedUser.firstName, storedUser.lastName );Keep in mind that some native data types cannot be serialized / deserialized using AMF . This applies to such visual objects, such as DisplayObject . For example, if you try to “parse” an instance of MovieClip (if it could be done, it would be very cool =), then you will not succeed:
// Создаём ByteArray
var bytes:ByteArray = new ByteArray();
// Пытаемся сохранить объетк DisplayObject
bytes.writeObject ( new MovieClip() );
// Сбрасываем позицию
bytes.position = 0;
// outputs : undefined
trace ( bytes.readObject() );Support for visual objects in AMF3 would be a very useful addition to the list of types supported in AMF .
From translator
I like to “pack” all commonly used functions into separate classes with static functions, and this case with copying objects was no exception =) For this, I created a small class and tried to save some of my class in the described way, during a little experiment I came across a small nuance , which is not described in the original article: if the constructor of the classes of the type you need requires the transmission of the required parameters, then an error will occur during the “restoration” of the object due to the fact that The desired data has been transmitted. Fortunately, this problem does not occur if the constructor requires passing parameters, but they are not required.
By the way, in my example, I tried to copy Array and Vector., And I did it all). Need to save / read data inI have SharedObject quite often, therefore, I think that this method of parsing and copying complex classes will be very, very useful to me.
Example Source