Пользовательский объект AS3 для ByteArray, а затем для пользовательского объекта - PullRequest
6 голосов
/ 18 сентября 2010

Возникли проблемы при чтении массива пользовательских объектов. Любая помощь приветствуется

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. 

Ответы [ 4 ]

12 голосов
/ 18 сентября 2010

Что вы хотите сделать, это использовать метод registerClassAlias ​​для регистрации информации о типе вместе с данными.Таким образом, Flash будет знать, как сериализовать / десериализовать ваш объект.Вот пример кода из документации Adobe :

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

Следует отметить, что все типы, которые должны быть сериализованы, должны быть зарегистрированы для сохранения информации о типе,Поэтому, если у вас есть другой тип, на который ссылается ваш тип, он тоже должен быть зарегистрирован.

1 голос
/ 18 сентября 2010

Ваш класс CustomObject неправильный, на самом деле он должен выдавать ошибку, это должно быть вместо этого

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

   public function CustomObject() 
   {
   }
}

Редактировать:

Похоже, что у Макке есть точка, потому что это работает ...


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

trace(obj) // [object Object]
trace(obj._z) // 60
0 голосов
/ 13 июня 2012

Чтобы сериализовать пользовательские классы в ByteArray, вы должны поместить registerClassAlias в конструктор класса, вызывающего функцию byteArray.writeObject().

Если нет, ваш пользовательский класс будет сериализованкак тип объекта.Я вызывал registerClassAlias в функции сериализации ниже, и мой пользовательский класс продолжает сериализоваться как Object, пока я не переместил registerClassAlias в конструктор.

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 голосов
/ 18 сентября 2010

Посмотрите на объект, который ByteArray.readObject() возвращает. Вы, вероятно, увидите, что все свойства есть, но информация о типе теряется. Таким образом, вы можете решить эту проблему, создав

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