Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/apache-flex/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache flex 在Flex中反序列化二进制对象时,对象初始化是如何发生的?_Apache Flex_Actionscript 3 - Fatal编程技术网

Apache flex 在Flex中反序列化二进制对象时,对象初始化是如何发生的?

Apache flex 在Flex中反序列化二进制对象时,对象初始化是如何发生的?,apache-flex,actionscript-3,Apache Flex,Actionscript 3,我想知道并着重于理解的jist是关于二进制反序列化如何在Flex3中发生的细节。什么时候调用构造函数,什么时候设置属性,私有成员是序列化的,还是所有的反序列化都在setter上发生,等等?我很难找到这方面的信息 在Flex 3 AIR应用程序中,我有一个非常复杂的对象图(只是一堆相互引用的对象,有点像大数据模型,只是有点复杂),我使用对FileStream.writeObject和根对象上的readObject的单个调用将其序列化为一个文件,这将序列化和反序列化整个对象图 我发现我需要始终有一个

我想知道并着重于理解的jist是关于二进制反序列化如何在Flex3中发生的细节。什么时候调用构造函数,什么时候设置属性,私有成员是序列化的,还是所有的反序列化都在setter上发生,等等?我很难找到这方面的信息

在Flex 3 AIR应用程序中,我有一个非常复杂的对象图(只是一堆相互引用的对象,有点像大数据模型,只是有点复杂),我使用对FileStream.writeObject和根对象上的readObject的单个调用将其序列化为一个文件,这将序列化和反序列化整个对象图

我发现我需要始终有一个默认构造函数,否则当反序列化对象时,如果它们是ArrayCollection的一部分,就会出现异常。因此,我必须删除构造函数参数或设置默认值。我现在在我的类中有很多这样的setter,比如下面的mConnection通过不同的setter积累了它需要的一些信息,就像以前一样,我把这些都打包到构造函数中,因为所有的信息对于连接的运行来说都是必需的:

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;
 }
}
在我添加序列化之前,这在很大程度上似乎工作得很好。我在应用程序关闭时序列化对象图,在应用程序打开时反序列化对象图。发生了什么事

当我添加序列化时,我遇到了一个问题,在反序列化之后,mConnection有时会有一个空字符串,有时会有被序列化的ip地址。我能说的最好的情况是,有时对象以不同的顺序反序列化,然后对象以不同的顺序分配给属性。因此,假设在序列化对象图时,我有一个客户端的存在,它引用了一个服务器实例和一个连接,反序列化过程中的一系列事件(仅调用readObject一次)可能是:

  • 连接被构造
  • 连接的属性是用反序列化的值设置的
  • 服务器是用默认构造函数构造的(serverIP的字符串为空)
  • 服务器值是反序列化的,并通过setter进行设置,将serverIP恢复为“127.0.0.1”或其他值
  • 客户端是构建的
  • 客户机的服务器属性被分配给先前构造的服务器实例,从而通过此setter设置连接的serverIP值
  • 在这种情况下,连接具有正确的服务器ip。我认为,下面的情况似乎是随机发生的,但有时会发生,导致反序列化完成后连接的serverIp成为空字符串

  • 连接被构造
  • 连接的属性是用反序列化的值设置的
  • 客户端是构建的
  • 服务器是用默认构造函数构造的(serverIP的字符串为空)
  • 客户端的服务器属性被分配给先前构造的服务器实例,从而通过此setter将连接的serverIP值设置为空字符串
  • 服务器值被反序列化并通过setter进行设置,从而将serverIP恢复为“127.0.0.1”或其他值
  • 因此,连接的serverIP仍然是空字符串,因为在服务器完全初始化之前,服务器已分配给客户端的属性

    我可能可以通过使用绑定来解决这个问题,以便将服务器中对serverip的更新绑定到连接,但我发现绑定属性相当复杂(在mxml的UI上非常简单,因为您只使用了方括号语法,但我发现通过代码来实现非常复杂)。我还通过完全删除构造函数参数解决了一些情况,因此没有默认值。除此之外,我还需要深入了解二进制序列化的细节,了解它如何重建对象图。我甚至有循环引用,它似乎可以很好地处理这些引用,并在不复制对象的情况下维护多个引用。只是当我的构造函数/设置器更复杂时,由于反序列化过程中发生的顺序,我遇到了这些问题。但这确实是不一致的,因为在不同的位置添加断点似乎会影响事情发生的顺序,从而使调试更加困难


    对于任何可能因为我正在序列化一个名为Connection的类而偏离主题的人,请注意。我添加了一些代码来解决一些问题,比如在Connection类中有一个套接字实例。当然,在我关闭并重新打开应用程序并反序列化它之后,我的套接字将不会被连接,因此在序列化我的对象图之前,我将遍历并关闭套接字,并将连接类中的引用设置为null,这样就不再有对套接字的引用,因此它将不会被序列化。在下一次应用程序运行反序列化之后,我创建了一个新套接字。

    有点旁注:您可以将静态函数用作伪重载构造函数

    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;
        }
    }
    
    (是的,我确实想念我的对象Pascal虚拟构造函数,为什么要问?)