⬆️ ⬇️

Copying objects using ByteArray

Copying simple objects



Most often, ByteArray is used to copy objects. AMF serializer and deserializer (I don’t like these words, but didn’t find a suitable translation) is available via 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 really 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 a User object on the server as binary data or locally in SharedObject . If you try to save a User object in ByteArray and retrieve it, then while reading Flash Player will check if User has been registered before, if not, this object will be “parsed” as a normal 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 ); 




To register the User type in Flash Player, you can use the registerClassAlias method. After this, 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 user-defined classes. As you can see, we are now working with a copy of a custom class object:



 storedUser.firstName = "Bobby"; storedUser.lastName = "Womack"; // outputs : Stevie Wonder trace ( myUser.firstName, myUser.lastName ); // outputs : Bobby Womack trace ( storedUser.firstName, storedUser.lastName ); 




It must be remembered 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” a MovieClip instance (if it could be done, it would be very cool =), then you will fail:



 //  ByteArray var bytes:ByteArray = new ByteArray(); //    DisplayObject bytes.writeObject ( new MovieClip() ); //   bytes.position = 0; // outputs : undefined trace ( bytes.readObject() ); 




The support of 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 frequently 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 manner described, in a small experiment I came across a small nuance , which is not described in the original article: if the class constructor of the type you need requires the transfer of required parameters, then when you “restore” the object, an error will occur due to the fact that the constructor did not have The required data has been transferred. Fortunately, this problem does not occur if the designer requires the transfer of parameters, but they are not mandatory.



By the way, in my example, I tried to copy Array and Vector., And I did it all). I often need to save / read data in SharedObject , so I think that this method of parsing and copying complex classes will be very, very useful to me.



Sample Source

Source: https://habr.com/ru/post/115502/



All Articles