我正在处理这样的场景:我的代码可能包含在其他 Flash 内容中,或者通过 import .as 命令包含,然后作为单例引用,例如
import com.as3.Singleton;
...
...
Singleton.birth();
Singleton.getInstance().test();
...但也作为运行时库导入;预先将 Singleton 类导出为 .swf(而不是预先烘焙该类)。
一旦 Event.COMPLETE 从引入 swf 的 Loader 中触发,我应该如何引用 Singleton?通常我会编写如下代码:
public function singletonCompleteHandler(event:Event):void {
var mySing:Singleton = _loader.contentLoaderInfo.content as Singleton;
}
...但我知道我不想通过“var”引用来引用单例。我解释得不是很好,但基本上一旦 singleton.swf 加载完毕,我就需要在单例模型中使用其中的代码(即确保在我的应用程序中只有一个实例)。
下面包含 Singleton 类的副本(顺便感谢您对此的任何想法)。
package
{
public class Singleton extends Sprite
{
private static var instance:Singleton;
public function Singleton() {
if (instance) {
throw new Error("Singleton can only be accessed through Singleton.getInstance()");
}
}
public static function birth() {
if (instance == null) {
instance = new Singleton();
}
}
public static function getInstance():Singleton {
return instance;
}
public function test():void {
trace("Testing our singleton.");
}
}
}
最佳答案
首先,如果您要动态加载它,那么您不希望在加载的 SWF 中引用它(否则就会破坏要点)。
所以我猜你想做这样的事情:
function completeHandler(event:Event):void
{
var singleton:Object = loader.contentLoaderInfo.content;
var instance:IMyObject = singleton.getInstance();
instance.test();
}
IMyObject
在这里当然是可选的。如果您这样做,您的单例实例将必须实现 IMyObject
。
interface IMyObject
{
function test():void;
}
这都是为了避免在加载 SWF 时引用实际的类。正如我所说,该接口(interface)是可选的:您可以只使用 Object
来代替。
...现在进入要点:将单例 SWF 加载到加载 SWF 自己的“应用程序域”中。
var lc:LoaderContext = new LoaderContext();
lc.applicationDomain = ApplicationDomain.currentDomain;
loader.load(new URLRequest("Singleton.swf"), lc);
您会看到,通常当您加载 SWF 时,它会加载到自己的应用程序域中。但这使得无法在加载的 SWF 上强制执行单例模式,因为该类的每个实例都可以存在于其自己的应用程序域中(因此您最终可能会获得多个实例)。因此,如果您想在多个 SWF 加载之间强制执行此操作,那么您需要将其加载到加载 SWF 的应用程序域中。
关于actionscript-3 - 管理外部 swf 中的单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5397196/