有没有一种方法可以清除AS3/AIR中嵌入的位图资源?

3

第一次在这里发帖。

我正在创建一个AIR 3.0应用程序。

对于我的大量图形资源,我使用Flex embed元数据将位图对象作为类嵌入,然后实例化它们。

问题是似乎它们永远不会被垃圾收集。我在网上没有找到太多信息,但我看到了一些帖子似乎证实了这一点。

每当我实例化其中一个具有这些嵌入式资源的类时,它们总是创建位图和位图数据的新实例,而不是重用已经存在于内存中的内容。这对于内存来说是一个巨大的问题。我无法找到任何方法将其取消引用或使其离开内存。

所以我能想到的唯一解决方案就是从磁盘加载图形而不是使用嵌入标签。但是,我不想这样做,因为当应用程序打包和安装时,所有这些图形资产将在最终用户计算机上而不是包含在SWF文件内。

有人遇到过这个问题吗?有解决方案吗?或者除我能想到的解决方案之外是否还有其他替代方案?

谢谢! Kyle

2个回答

1

嗯,我想这是预期的行为,因为新操作符应该总是创建新对象。但是那些新对象应该被垃圾回收,只有资产类不会,因为它是一个类。

您可以构建一个像单例工厂一样的缓存。您通过指定ID请求图像,缓存将创建该图像(如果尚不存在),或者如果已存在,则返回单个实例。我已经很久没有编写ActionScript了,所以也许您应该将其视为伪代码 ;)

public class Cache {

    import flash.utils.Dictionary;
    import flash.utils.getDefinitionByName;

    [Embed(source="example.gif")]
    public static var ExampleGif:Class;

    /**
     * The single instance of the cache.
     */
    private static var instance:Cache;

    /**
     * Gets the Cache instance.
     *
     * @return
     *     The Cache
     */
    public static function getInstance():Cache {
        if (Cache.instance == null) {
            Cache.instance = new Cache();
        }
        return Cache.instance;
    }

    /**
     * The cached assets are in here.
     */
    private var dictionary:Dictionary

    public function Chache() {
        if (Cache.instance != null) {
            throw new Error("Can not instanciate more than once.");
        }
        this.dictionary = new Dictionary();
    }

    /**
     * Gets the single instantiated asset its name.
     *
     * @param assetName
     *     The name of the variable that was used to store the embeded class
     */
    public function getAsset(assetName:String):Object {
        if (this.dictionary[assetName] == null) {
            var AssetClass = getDefinitionByName(assetName) as Class;
            this.dictionary[assetName] = new AssetClass();
        }
        return this.dicionary[assetName];
    }

}

你可以像这样使用它:
public class Example {

    public static function main() {
        Bitmap exampleGif1 = Cache.getInstance().getAsset("ExampleGif") as Bitmap;
        Bitmap exampleGif2 = Cache.getInstance().getAsset("ExampleGif") as Bitmap;
        trace("both should be the same instance: " + (exampleGif1 == exampleGif2));
    }

}

我没有测试过这个,如果可以的话请告诉我。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接