如何序列化 Vector.<Customobject>? [英] How do I serialize Vector.&lt;Customobject&gt;?

查看:21
本文介绍了如何序列化 Vector.<Customobject>?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

http://jacksondunstan.com/articles/1642我遇到了问题.我正在尝试保存一堆图标.它们有一个自定义类Iconn",并存储在 Vector. 中以备将来使用.一旦用户添加了一个新图标,我就会打开一个文件流并使用它来编写整个矢量.

http://jacksondunstan.com/articles/1642 I followed this to the T, yet I'm running into issues. I'm trying to save a bunch of icons. They have a custom class "Iconn" and are stored in a Vector.<Iconn> for future use. Once the user adds a new icon, I open up a filestream and use it to write the entire vector.

        public function addShortcut(f:File):void
    {
        //Display on side
        icons.reverse(); //Add to the front so it displays on the top.
        icons.push(new Iconn(f)); //Use 16x16 bitmap

        addChild(icons[icons.length - 1]);
        icons.reverse();

        //Save object
        fs = new FileStream();
        fs.open(shortcuts, FileMode.WRITE);
        fs.writeObject(icons);
        fs.close();

        reorder(); //Reorganizes the icons on the screen.
    }

这一切正常,没有错误,但是当我尝试在保存了一些图标的情况下重新启动应用程序时,该矢量甚至不存在.

This works all and well with no errors, but when I try to re-launch the application with some icons saved, the vector doesn't even exist.

    icons = new Vector.<Iconn>();
    if (shortcuts.exists)
    {
        trace("Shortcuts exist..adding");
        fs = new FileStream();
        fs.open(shortcuts, FileMode.READ);
        icons = fs.readObject() as Vector.<Iconn>;
        fs.close();
        trace("icons = " + icons); //TypeError: Error #1009: Cannot access a property or method of a null object reference.
        trace("icons length  = " + icons.length); //TypeError: Error #1009: Cannot access a property or method of a null object reference.
    }

我尝试添加 registerClassAlias("Vector.", Vector.,但随后出现编译器错误1067:隐式强制类型为 __AS3__.vec:Vector. 的值到一个不相关的类型类.

I tried adding registerClassAlias("Vector.<Iconn>", Vector.<Iconn>);, but then I get a compiler error 1067: Implicit coercion of a value of type __AS3__.vec:Vector.<Iconn> to an unrelated type Class.

这是我的 Iconn 类 http://pastebin.com/5TujzpvR

Here is my Iconn class http://pastebin.com/5TujzpvR

推荐答案

这不起作用有几个原因.

There's a few reasons this isn't working.

  1. 当对象被反序列化时,你不能将参数传递给它们的构造函数.这意味着您要么需要取出嵌套在对象中的所有类的所有构造函数参数,要么通过为它们提供默认值来使它们全部可选.

  1. When objects are unserialized, you cannot pass parameters to their constructors. This means that you either need to take out all constructor arguments of ALL classes nested inside your object, or make them all optional by giving them default values.

您必须注册每个在被序列化的对象中使用的非原始类(包括对象的类本身).这包括嵌套类.就您而言,这至少包括:

You have to register every single non-primitive class you use in the object being serialized (including the object's class itself). This includes nested classes. In your case, this includes at least:

flash.display.Bitmap;
flash.display.Sprite;
flash.events.MouseEvent;
flash.filesystem.File;
fl.transitions.Tween;
fl.transitions.easing.Strong;

加上这些类中引用的任何内容.

Plus anything referenced inside of those classes.

序列化显示对象不起作用*(技术上可以使用实现 IExternalizable,但它非常复杂).如果你想要一个例子,有一个这里.

Serializing display objects just doesn't work* (it is technically possible with a custom class that implements IExternalizable, but it's quite involved). If you want an example, there is one here.

<小时>

序列化显示对象的最佳方法是创建一个非常基本的类,其中包含重建显示对象所需的最少数据.


The best way to serialize display objects, is to create a very very basic class that contains the bare minimum data needed to reconstruct your display object.

就您而言,看起来您真正需要的只是位图数据.因此,您可以创建一个如下所示的简单类:

In your case, it looks like all you really need is bitmap data. So you could make a simple class like the following:

package 
{
    import flash.geom.Rectangle;
    import flash.utils.ByteArray;

    public class SaveData 
    {
        public var imgBytes:ByteArray;
        public var bounds:Rectangle;
        public var transparent:Boolean;
    }
}

它存储的只是原始位图数据(像素值的字节数组)和位图的边界.

All it stores is the raw bitmap data (a byte array of pixel values), and bounds of the bitmap.

首先,您需要注册所有使用的类.看起来像这样:

First, you need to register all the classes used. That would look like this:

        //you need to register your class that you're using writeObject on
        registerClassAlias("SaveData", SaveData); 

        //you also need to register the two classes that are referenced in your SaveData class
        registerClassAlias("flash.utils.ByteArray", ByteArray);
        registerClassAlias("flash.geom.Rectangle", Rectangle);

        //you ALSO need to register Point since it's referenced inside the Rectangle class
        registerClassAlias("flash.geom.Point", Point);

现在,为了保存它,主要做你已经在做的事情:

Now, to save it, do mostly what you're already doing:

//create a vector to store your list of items to save
var saveArray:Vector.<SaveData> = new Vector.<SaveData>();

//loop through all your icons and do the following in the loop (where bitmap is the icon's bitmap):

var saveData:SaveData = new SaveData();
saveData.bounds = bitmap.getBounds(bitmap);
saveData.imgBytes = bitmap.bitmapData.getPixels(saveData.bounds);
saveData.transparent = bitmap.bitmapData.transparent;
saveArray.push(saveData);

//write the Vector to the file
fs = new FileStream();
fs.open(shortcuts, FileMode.WRITE);
fs.writeObject(saveArray);
fs.close();

现在,当您准备好将其全部加载回来时:

Now, when you're ready to load it all back in:

fs = new FileStream();
fs.open(shortcuts, FileMode.READ);
var saveArray:Vector.<SaveData> = fs.readObject() as Vector.<SaveArray>;
fs.close();

//now loop through your array and re-create all your icons.

for(var i:int=0;i<saveArray.length;i++){
    var bmd:BitmapData = new BitmapData(saveArray[i].bounds.width, saveArray[i].bounds.height, saveArray[i].transparent);
    bmd.setPixels(saveArray[i].bounds, saveArray[i].imgBytes);

    var bitmap:Bitmap = new Bitmap(bmd);

    //instead of passing in a file to your Iconn class, tweak it so you pass in a bitmap:
    var icon:Iconn = new Iconn(bitmap);

    //do what you need to do with he icon
}

这篇关于如何序列化 Vector.<Customobject>?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆