在Flex中反序列化二进制对象时,如何进行对象初始化?

Aar*_*nLS 7 apache-flex actionscript-3

的想什么,我知道并专注于JIST 理解,是如何反序列化的二进制在Flex 3中发生的细节.当被称为构造函数,当属性设置,是私有成员序列化或不全部反序列化发生在通过制定者等等?我很难找到相关信息.

在Flex 3 AIR应用程序,我有一个非常复杂的对象图(只是一堆引用彼此,有点像只是稍微复杂一些大的数据模型对象),我序列化到使用上的FileStream单个调用的文件.对象上的writeObject和readObject,用于序列化和反序列化整个对象图.

我发现我需要总是有一个默认的构造函数,否则我会在反序列化时获得对象的异常,如果它们是ArrayCollection的一部分.所以我必须腾出构造函数参数或设置默认值.我现在有很多制定者像这样在我的课,如下面的地方mConnection积累,需要通过不同的制定者,在那里像以前我有这一切包装成因为所有的信息构造一些信息确实necesary用于连接功能:

class Client
{
 private var mConnection:Connection;
 public function get connection():Connection{ return mConnection; }

 public var mUser:User;
 public function get user():User { return mUser; }
 public function set user(value:User):void 
 {
  mUser = value;
  mConnection.username = user.username;
  mConnection.password = user.password;
 }

 private var mServer:Server;
 public function get server():Server { return mServer;}
 public function set server(value:Server):void 
 { 
  mServer = value;
  mConnection.serverIP = value.serverIP;   
 }

 public function Client()
 {
  mConnection = new Connection();
 }   
}

public class Server
{
 [Bindable]
 public var Clients:ClientsCollection  = new ClientsCollection( );//contains Client type 
 private var mServerIP:String;
 public function get serverIP():String { return mServerIP; }
 public function set serverIP(value:String):void 
 {
  mServerIP = value;
  serverName = mServerIP;
 }

 public var serverName:String;

 public function Server(serverIP:String = "")
 { 
  this.serverIP = serverIP;
 }
}
Run Code Online (Sandbox Code Playgroud)

在添加序列化之前,这似乎在大多数情况下都能正常工作.我在应用程序关闭时序列化对象图,并在应用程序打开时反序列化它.我发生了什么

当我添加序列化时,我遇到的问题是,在反序列化之后,mConnection有时会有一个空字符串,有时会有序列化的ip地址.我能说的最好的事情是,有时候对象以不同的顺序反序列化,然后按不同的顺序将对象分配给属性.因此,让我们在序列化对象图的时候说,我有一个客户端的isntance,具有服务器和连接,和反序列化(刚的readObject单个呼叫)过程中的事件一个序列的实例的引用可能:

  1. 建立连接.
  2. Connection的属性使用反序列化值设置.
  3. 服务器使用默认构造函数构造(对于serverIP具有空字符串)
  4. 服务器值已经过设置并通过setter进行设置,将serverIP恢复为"127.0.0.1"或其他任何内容.
  5. 客户端构建
  6. 客户端的服务器属性与先前构造的服务器实例一起分配,从而导致通过此setter设置连接的serverIP值.

在这种情况下,Connection具有正确的服务器IP.我认为,看似随机,但有时会发生以下情况,导致连接的serverIp在反序列化完成后变为空字符串.

  1. 建立连接.
  2. Connection的属性使用反序列化值设置.
  3. 客户端构建
  4. 服务器使用默认构造函数构造(对于serverIP具有空字符串)
  5. 客户端的服务器属性与先前构造的服务器实例一起分配,导致连接的serverIP值通过此setter 设置为空字符串.
  6. 服务器值被反序列化并通过setter进行设置,将serverIP恢复为"127.0.0.1"或其他任何内容.

因此,连接的serverIP仍然是一个空字符串,因为在服务器完全初始化之前,服务器已分配给客户端的属性.

我可以通过使用绑定,以便更新服务器的SERVERIP绑定到连接可能解决这个问题,但我觉得结合性能进行相当复杂(这是很简单的UI在MXML因为你只需要使用大括号语法,但这样做它通过代码是我发现的复杂).我还通过完全删除构造函数参数解决了一些情况,因此没有默认值.除此之外,我仍然需要更深入地了解二进制序列化的细节,就像它如何重建对象图一样.我甚至有循环引用,它似乎处理那些罚款和维护多个引用而不重复对象.只是当我的构造函数/ setter更复杂时,由于反序列化过程中出现的顺序,我遇到了这些问题.但它确实是不一致的,因为在各个地方添加断点似乎会影响事件发生的顺序,使调试更加困难.

对于那些可能会偏离主题的人来说,因为我正在序列化一个名为Connection的类.我添加了一些代码来解决一些问题,比如在Connection类中有一个Socket实例.当然,我的插座将不连接后,我关闭并重新打开应用程序和反序列化,所以在序列化我的对象图,我经过,并在连接类为null关闭套接字,设置基准,所以不存在更长的对套接字的引用,因此它不会被序列化.在下一个应用程序运行后反序列化后,我创建一个新的套接字.

Ric*_*ven 1

旁注:您可以使用静态函数作为伪重载构造函数

class Fred
{
    public function Fred()
    {
        // boring, default constructor with no parameters
    }

    public static function Freddy(aValue1 : String, aValue2 : Object = null) : Fred
    {
        var result : Fred = new Fred();

        result.value1 = aValue1;
        result.value2 = aValue2;

        return result;
    }
}
Run Code Online (Sandbox Code Playgroud)

(是的,我确实想念我的 Object Pascal 虚拟构造函数,你为什么问这个?)