views:

27

answers:

3

Having problem reading bytearray of custom objects. Any help is appreciated

public class CustomObject extends Object {
public function CustomObject() {
public var _x:Number =  100
public var _y:Number = 10
public var _z:Number  = 60
}
}

var cObj:CustomObject = new CustomObject()
var bytes:ByteArray = new ByteArray()
bytes.writeObject(cObj)
bytes.compress()

//read
try { bytes.uncompress() } catch (e:Error) { }
var obj:CustomObject = bytes.readObject() as CustomObject

trace(obj) // null why?!
trace(obj._z) // Obviously - TypeError: Error #1009: Cannot access a property or method of a null object reference. 
A: 

Look at object that ByteArray.readObject() returns. You'll probably see that all properties are there, but type information is lost. So, you can solve this by creating some

public static function fromObject(value:Object):CustomObject {
    var result:CustomObject = new CustomObject();
    result._x = value._x;
    //and so on...
    return result;
}
alxx
the problem is custom object have another custom object in it...for example cObj._myHome = myHome, where myHome:MyHome extends object
Exoot
+1  A: 

Your CustomObject class is wrong , it should throw an error actually , it should be this instead

public class CustomObject 
{
   public var _x:Number =  100
   public var _y:Number = 10
   public var _z:Number  = 60

   public function CustomObject() 
   {
   }
}

Edit:

Sounds like macke has a point, because this works...


//read
try { bytes.uncompress() } catch (e:Error) { }
var obj:Object = bytes.readObject();

trace(obj) // [object Object]
trace(obj._z) // 60
PatrickS
i dont think that would matter in this case does it?
Exoot
i'm not sure actually , would need to test it... the CustomObject class is a bigger problem though!
PatrickS
awesome var obj:Object = bytes.readObject(); and registerClassAlias("com.example.eg", ExampleClass); does the trick
Exoot
and about the CustomObject theres syntax error in the question, but in the actual class it is correctly coded..
Exoot
+3  A: 

What you want to do is use the registerClassAlias method to register type information along with the data. That way Flash will know how to serialize/deserialize your object. Here's some sample code from Adobe's documentation:

registerClassAlias("com.example.eg", ExampleClass);
var eg1:ExampleClass = new ExampleClass();
var ba:ByteArray = new ByteArray();
ba.writeObject(eg1);
ba.position = 0;
var eg2:* = ba.readObject();
trace(eg2 is ExampleClass); // true

It should be noted that all types that should be serialized must be registered for the type information to be saved. So if you have another type that is referenced by your type, it too must be registered.

macke
woah register class, sounds expensive..does that cause any performance issues or what, ah i'll google it
Exoot
Not really. It does store information about the type in the data, but it's not too inefficient. It doesn't really affect processing either all that much. It's used to store objects in the AMF protocol which is widely used for data transfer in the Flash platform. Other than manually storing type information and providing manual conversion from raw object data to specific types, this is your only option really and it's not bad.
macke
yea I use 'custom' objects so that its faster than the new Object(); so wondered if it could cause performance issues in weird as3
Exoot
Unless you have huge object graphs or serialize/deserialize huge amounts of object consistently, I wouldn't worry about it. In either case, adding typing information would probably be the least of your troubles.
macke