可外部化 (as3)
有人用过 IExternalized 接口吗? ...
我有一个基本问题。当我序列化我的对象...并保存为文件...现在我想在类中进行一些更改...例如添加属性...我无法将文件重新转换为此类的对象...因为在 readExternal 方法中现在多了一个属性,存储的对象(文件)不拥有该属性....
有没有一种方法可以使其更加灵活?
-- // 德语
Hallo hat 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 ... 威尔在德readExternal methode nun ein Attribute mehr abgefragt wird, welches das gespeicherte Objekt (Datei) nicht besitzt....
gibts da Möglichkeiten das flexr zu machen?
has anyone used the IExternalizable interface? ...
I have a fundamental question. When I haved serialized my object ... and have saved as a file .... and now I wants to make some changes in the class ... e.g. add an attribute ... I can not re-convert the file into an object of this class ... because in the readExternal method is now one more attribute, which the stored object (file) does not own ....
is there a way to make this more flexible?
-- // german
Hallo hat 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... z.B. 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 wird, welches das gespeicherte Objekt (Datei) nicht besitzt....
gibts da Möglichkeiten das flexibler zu machen?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您必须使用以下方式注册该类的别名
flash.net.registerClassAlias
函数。这个东西添加了一些元数据(如果我是正确的)到写入的 Amf 对象中,允许 Flash 确定原始类。然后从文件系统或网络将文件加载为 ByteArray 并使用 ByteArray#readObject() 方法读取对象。
有关此的更多信息:
http://help.adobe.com/en_US /FlashPlatform/reference/actionscript/3/flash/net/package.html
You have to register alias of that class by using
flash.net.registerClassAlias
function. This thing adds some metadata (if I'm correct) to writen Amf object that alows Flash to determine original Class.Then load you file from file system or network as ByteArray and read object by using
ByteArray#readObject()
method.More info on this:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/package.html
如果您要添加、删除或更改类的属性,则这是不兼容的 API 更改。考虑一下您的类是否是其他开发人员(例如您的同事,或者如果您的库是开源的,任何下载它并开始使用它来制作项目的人)已经使用的软件库的一部分,如果您制作了不兼容的像这样改变,其他人的代码可能会立即停止工作或工作不正确。这种 API 更改应该只允许在主要新版本之间发生(例如,您的库版本是 v1.XY,而您发布了 v2.0.0)。
当您将 SomeClass 的实例序列化到文件时,类名也会存储在该文件中,因此当从文件中读回该实例时,Flash 将知道要创建哪个类的实例。但是请考虑一下,如果您更改 API,它就不再是相同的 SomeClass,名称相同但类定义不同。没有简单的方法可以解决这个问题。
如果您确实需要保留对该文件中数据的访问权限。一个简单的解决方案是将版本信息作为第一项存储在数据文件中。每次更改文件格式时,都应该增加版本。写入文件时,先写入当前版本。读取文件时,读取当前版本并将其作为公共静态属性存储在可以从项目中的任何位置访问的类中(例如,创建一个单独的类 DataLoaderInfo 和一个公共静态 var formatVersion:String 或 uint)。然后像以前一样继续阅读您的文件。在你要修改的类 SomeClass 中,它看起来像这样:
你可以想象,如果你有很多文件格式版本,代码可能会变得相当复杂。这完全取决于您正在开发什么类型的应用程序以及可以同时在现场部署多少个版本。例如,如果您的应用程序是移动应用程序,将其设置或状态存储在二进制文件中,则每个用户可能会以不同的时间间隔进行更新,因此用户可能会从不同的旧版本升级到最新版本,因此您的应用程序应该能够优雅地加载所有这些版本的配置。如果您的所有数据都存储在您自己的服务器上,并且对这些数据的唯一访问是通过您的服务器上部署的最新版本的应用程序,则您只需要支持上次部署的版本和当前(新)版本的格式版本。
您还可以考虑制作一个单独的实用程序应用程序来将数据文件转换为更新的格式。
1) 创建原始类 SomeClass 的子类 ExtSomeClass。将新的 API(例如属性)添加到子类中。重写类的 IExternalized 方法 - 首先调用 super 的方法,然后读取/写入添加的新属性。
2) 创建一个实用程序转换应用程序来读取包含 SomeClass 实例的原始文件。对于您阅读的每个 SomeClass,您应该创建 ExtSomeClass 的一个新实例,复制所有 SomeClass 的属性并使用一些合理的默认值初始化 ExtSomeClass 属性。因此 SomeClass 的每个实例都会被 ExtSomeClass 替换。将转换后的数据写回您的文件。
如果您不想创建子类,并且确实想修改原始类 SomeClass,您也可以这样做,但转换代码会更加棘手,因为您需要访问旧版本和新版本类,显然你不能在项目中编译两个同名的类,你必须将新的(更新的)类编译到单独的 SWF 中,转换应用程序应该使用旧版本的 SomeClass 进行编译,然后你可以读取您的旧版本文件,每个实例SomeClass 将使用旧版本的类正确读取。使用 Loader 加载包含新(更新)类的 SWF,您可以使用 loader.loaderInfo.applicationDomain.getDefinitionByName 来获取对新类的引用,您可以通过这种方式创建新类的实例,然后复制您从文件中读取的实例的所有属性。
If you're adding, removing or changing an attribute to your class, this is an incompatible API change. Consider if your class is a part of an software library already used by other developers (e.g. your co-workers, or if your library is open-source, anybody who downloaded it and started making their project using it), if you make an incompatible change like that, immediately other people's code might stop working or work incorrectly. This kind of API change should only be allowed to happen between major new releases (e.g. your library version was v1.X.Y and you release a v2.0.0).
When you serialized the instance of your SomeClass to a file, the class name is also stored in that file, so when reading that instance back from the file, Flash will know an instance of which class to create. However consider that if you change your API, it's no longer the same SomeClass, the name is the same but the class definition is different. There's no easy way around it.
If you really need to keep access to the data in that file. A simple solution would be to store version info in your data file as the first item. Every time you change the file format, you should increment the version. When writing the file, write the current version first. When reading the file, read the current version and store it as a public static property in a class that can be accessed from anywhere in your project (e.g. create a separate class DataLoaderInfo and a public static var formatVersion:String or uint). Then keep reading your file as you did before. In your class SomeClass, which you want to modify, would look like this:
You can imagine, if you have many file format versions, the code might become quite complicated. It all depends what kind of application you're developing and how many versions might be deployed in the field at the same time. For example, if your app is a mobile app, storing it's settings or state in a binary file, each user might update at different intervals, therefore a user might upgrade to your latest version from different older versions, so your app should be able to gracefully load configs of all these versions. If all your data is stored on your own server, and the only access to this data is through the latest version of your app deployed on your server as well, you only need to support formats of the last deployed version and the current (new) version.
You might also consider making a separate utility app to convert your data file to the updated format.
1) Create a subclass ExtSomeClass of your original class SomeClass. Add your new API (e.g. properties) to the subclass. Override the IExternalizable methods of the class - call super's methods first, then read/write the added new properties.
2) Make a utility conversion app that reads your original file, containing instances of SomeClass. For every SomeClass that you read, you should create a new instance of ExtSomeClass, copying all SomeClass's properties and initializing ExtSomeClass properties with some reasonable defaults. So every instance of SomeClass gets replaced by ExtSomeClass. Write the converted data back to your file.
If you don't want to make a subclass, and want to indeed modify the original class SomeClass, you can also do that, but the conversion code will be more tricky, since you'll need access to both old and new versions of your class, obviously you can't have two classes with same name compiled in your project, you would have to compile your new (updated) class into a separate SWF, the conversion app should be compiled using the old version of SomeClass, then you can read your old-version file, every instance of SomeClass will be read correctly using the old version of your class. Load the SWF containing your new (updated) class using Loader, you can use
loader.loaderInfo.applicationDomain.getDefinitionByName
to get a reference to your new Class, you can create instances of the new class this way, and then copy all the properties from the instances you read from the file.