2012-03-15 62 views
3

中的嵌入式位图资产首次在此处发布。有没有办法清除AS3/AIR

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

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

问题是,它似乎从来没有收到垃圾。我没有在网上找到很多信息,但我看过一些似乎证实这一点的帖子。

无论何时,我的一个类被实例化为具有这些嵌入资源,它们总是创建Bitmaps和BitmapDatas的新实例,而不是重用已存在的内容。这是一个巨大的记忆问题。而且我找不到任何方式去取消它们或让它们留下记忆。

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

Anyoen碰到这个?有一个解决方案?或者我可以想到的替代解决方案?

谢谢! Kyle

回答

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)); 
    } 

} 

我没有测试此,所以让我知道它是否有效。

相关问题