有没有办法清除AS3 / AIR中的嵌入式Bitmap资产

时间:2012-03-15 18:45:10

标签: actionscript-3 actionscript air garbage-collection adobe

第一次在这里发帖。

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

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

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

无论何时我的一个类被实例化都有这些嵌入式资产,它们总是创建Bitmaps和BitmapDatas的新实例,而不是重用已经在内存中的内容。这对于记忆来说是一个巨大的问题。我找不到任何解除他们的方式或让他们留下记忆的方式。

所以我能想到的唯一解决方案就是从磁盘加载图形而不是使用embed标签。但我不想这样看看应用程序的打包和安装方式,所有这些图形资产都将在最终用户计算机上,而不是包含在SWF中。

Anyoen遇到了这个?有解决方案吗?或者是我能想到的替代解决方案?

谢谢! 凯尔

2 个答案:

答案 0 :(得分:1)

嗯,我猜这是预期的行为,因为new运算符应该始终创建新对象。但是这些新对象应该被垃圾收集,只有资产类不会,因为它是一个类。

您可以构建一个类似于单件工厂的缓存。您通过指定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));
    }

}

我没有对此进行测试,请告诉我它是否有效。

答案 1 :(得分:0)

我认为你要找的是dispose()http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/BitmapData.html?#dispose()

如果你决定使用缓存系统,这里有一些代码 测试http://thanksmister.com/2009/01/29/flex-imagecache-a-cheap-way-to-cache-images/。它使用SuperImage对另一种技术的链接已被破坏,但我设法找到了这个http://demo.quietlyscheming.com/superImage/app.html