2010-09-18 5 views
6

Problème lors de la lecture de bytearray d'objets personnalisés. Toute aide est appréciéeObjet personnalisé AS3 à ByteArray puis à l'objet personnalisé

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. 

Répondre

12

Ce que vous voulez faire est d'utiliser le registerClassAlias méthode pour enregistrer des informations de type avec les données. De cette façon, Flash saura sérialiser/désérialiser votre objet. Voici quelques exemples de code à partir d'Adobe 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 

Il convient de noter que tous les types qui doivent être sérialisés doivent être enregistrés pour les informations de type à enregistrer. Donc, si vous avez un autre type qui est référencé par votre type, il doit aussi être enregistré.

+1

woah classe de registre, sonne cher .. qui pose des problèmes de performance ou quoi, ah je vais google – kornesh

+2

Pas vraiment. Il stocke des informations sur le type dans les données, mais ce n'est pas trop inefficace. Cela n'affecte pas vraiment le traitement. Il est utilisé pour stocker des objets dans le protocole AMF qui est largement utilisé pour le transfert de données dans la plate-forme Flash. Autre que de stocker manuellement des informations de type et de fournir une conversion manuelle à partir de données d'objet brut à des types spécifiques, c'est votre seule option vraiment et ce n'est pas mauvais. –

+0

Oui j'utilise des objets 'personnalisés' pour que ce soit plus rapide que le nouveau Object(); Je me demandais si cela pouvait causer des problèmes de performance dans un environnement bizarre. – kornesh

0

Regardez à l'objet que ByteArray.readObject() renvoie. Vous verrez probablement que toutes les propriétés sont présentes, mais les informations de type sont perdues. Ainsi, vous pouvez résoudre ce problème en créant une

public static function fromObject(value:Object):CustomObject { 
    var result:CustomObject = new CustomObject(); 
    result._x = value._x; 
    //and so on... 
    return result; 
} 
+0

le problème est objet sur mesure ont un autre objet personnalisé en elle ... par exemple cObj._myHome = myHome, où myHome: MyHome étend l'objet – kornesh

1

Votre classe CustomObject est faux, il doit lancer une erreur en fait, il devrait être ce lieu

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

    public function CustomObject() 
    { 
    } 
} 

Edit:

Sonne comme Macke a un point, parce que cela fonctionne ...

 

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

trace(obj) // [object Object] 
trace(obj._z) // 60 
+0

je ne pense pas que cela importe dans ce cas il fait? – kornesh

+0

je ne suis pas sûr, en fait, aurait besoin de le tester ... la classe CustomObject est un plus gros problème si! – PatrickS

+0

awesome var obj: Objet = octets.readObject(); et registerClassAlias ​​("com.example.eg", ExampleClass); fait l'astuce – kornesh

0

Pour sérialiser des classes personnalisées au ByteArray, vous devez mettre registerClassAlias dans le constructeur de la classe appelant la fonction byteArray.writeObject(). Si ce n'est pas le cas, votre classe personnalisée sera sérialisée en tant que type d'objet. J'appelais registerClassAlias dans la fonction serialize ci-dessous et ma classe personnalisée continue d'être sérialisée en tant que Object jusqu'à ce que j'ai déplacé le registerClassAlias au constructeur.

public class MyClass{ 
    public function MyClass(){ 
     registerClassAlias("com.myclass", MyClass); // Ok, serializes as MyClass 
     serialize(new MyClass()); 
    } 

    private function serialize(_c:MyClass){ 
     var byteArray:ByteArray = new ByteArray(); 
     byteArray.writeObject(_c); 
     //registerClassAlias("com.myclass", MyClass); Not ok, serialized as Object 
     EncryptedLocalStorage.setItem('key', byteArray); 
    } 
} 
+0

l'appel à registerClassAlias ​​doit précéder l'appel à ByteArray: writeObject, mais il ** ne doit pas être dans le constructeur de la classe à sérialiser. –

Questions connexes