1

有人用过 IExternalizable 接口吗?...

我有一个基本问题。当我序列化我的对象......并保存为文件......现在我想在类中进行一些更改......例如添加一个属性......我无法将文件重新转换为此类的对象...因为在 readExternal 方法中现在多了一个属性,存储的对象(文件)不拥有该属性...。

有没有办法让这更灵活?

-- // 德语

你好帽子 schon mal jemand das im Titel erwähnte Interface benutzt?...

Habe mal ne grundlegende Frage dazu。Wenn ich mein Objekt serialisiert habe... und als Datei abgespeichert habe.... und nun in der Klasse einige Änderungen vornehmen möchte... zB ein Attribut hinzufügen... dann kann ich die Datei nicht wieder in ein Objekt dieser Klasse umwandeln ... weil in der readExternal methode nun ein Attribute mehr abgefragt wrd, welches das gespeicherte Objekt (Datei) nicht besitzt....

gibts da Möglichkeiten das flexibler zu machen?

4

2 回答 2

2

flash.net.registerClassAlias您必须使用函数注册该类的别名 。这件事向 writen Amf 对象添加了一些元数据(如果我是正确的),该对象允许 Flash 确定原始类。

然后从文件系统或网络加载文件作为 ByteArray 并使用ByteArray#readObject()方法读取对象。

更多信息: http ://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/package.html

于 2011-11-09T17:46:57.947 回答
1

如果您要添加、删除或更改类的属性,这是不兼容的 API 更改。考虑您的课程是否是其他开发人员已经使用的软件库的一部分(例如您的同事,或者您的库是开源的,任何下载它并开始使用它的项目的人),如果您制作了不兼容的像这样改变,其他人的代码可能立即停止工作或工作不正确。这种 API 更改应该只允许在主要的新版本之间发生(例如,您的库版本是 v1.XY,而您发布的是 v2.0.0)。

当您将 SomeClass 的实例序列化为文件时,类名也存储在该文件中,因此当从文件中读取该实例时,Flash 将知道要创建哪个类的实例。但是请考虑,如果您更改 API,它不再是相同的 SomeClass,名称相同但类定义不同。没有简单的方法解决它。

如果您确实需要继续访问该文件中的数据。一个简单的解决方案是将版本信息作为第一项存储在数据文件中。每次更改文件格式时,都应增加版本。写入文件时,先写入当前版本。读取文件时,读取当前版本并将其作为公共静态属性存储在可以从项目中的任何位置访问的类中(例如,创建单独的类 DataLoaderInfo 和公共静态 var formatVersion:String 或 uint)。然后像以前一样继续阅读您的文件。在您要修改的类 SomeClass 中,看起来像这样:

function readExternal(input:IDataInput):void {

    // Read format version 0 properties.
    oldIntProperty1 = input.readInt();
    oldIntProperty2 = input.readInt();
    ...
    // Read format version 1 properties.
    if (DataLoaderInfo.formatVersion >= 1) {
        newIntProperty1 = input.readInt();
        ...
    }
    // Read format version 2 properties.
    if (DataLoaderInfo.formatVersion >= 2) {
        ...
    }
    ...
}

您可以想象,如果您有许多文件格式版本,代码可能会变得相当复杂。这完全取决于您正在开发什么样的应用程序以及可能同时在现场部署多少个版本。例如,如果您的应用是移动应用,将其设置或状态存储在二进制文件中,每个用户可能会以不同的时间间隔更新,因此用户可能会从不同的旧版本升级到您的最新版本,因此您的应用应该能够优雅地加载所有这些版本的配置。如果您的所有数据都存储在您自己的服务器上,并且只能通过您服务器上部署的最新版本的应用程序访问这些数据,您只需要支持上次部署的版本和当前(新)的格式版本。

您也可以考虑制作一个单独的实用程序来将您的数据文件转换为更新的格式。
1) 创建原始类 SomeClass 的子类 ExtSomeClass。将您的新 API(例如属性)添加到子类。覆盖类的 IExternalizable 方法 - 首先调用 super 的方法,然后读取/写入添加的新属性。
2)制作一个实用程序转换应用程序来读取您的原​​始文件,其中包含 SomeClass 的实例。对于您阅读的每个 SomeClass,您应该创建一个 ExtSomeClass 的新实例,复制所有 SomeClass 的属性并使用一些合理的默认值初始化 ExtSomeClass 属性。所以 SomeClass 的每个实例都被 ExtSomeClass 替换。将转换后的数据写回您的文件。如果您不想创建子类,并且确实想修改原始类 SomeClass,您也可以这样做,但转换代码会更加棘手,因为您需要访问旧版本和新版本类,显然你不能在你的项目中编译两个同名的类,你必须将你的新(更新)类编译成一个单独的 SWF,转换应用程序应使用旧版本的 SomeClass 编译,然后您可以读取旧版本文件,SomeClass 的每个实例都将使用旧版本的类正确读取。使用 Loader 加载包含新(更新)类的 SWF,您可以使用loader.loaderInfo.applicationDomain.getDefinitionByName要获得对新类的引用,您可以通过这种方式创建新类的实例,然后从您从文件中读取的实例中复制所有属性。

于 2015-10-27T04:00:31.233 回答