在外部swfs中管理单身人士

时间:2011-03-22 20:09:52

标签: actionscript-3 design-patterns singleton flash external

我正在处理这样的场景,即我的代码可能包含在其他Flash内容中,或者通过import .as命令包含,然后引用为Singleton,例如

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

2 个答案:

答案 0 :(得分:4)

首先,如果您正在动态加载它,那么您不希望在加载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中的实际类。就像我说的,界面是可选的:你可以改用Object

...现在转到主要观点:将单例SWF加载到加载SWF自己的“应用程序域”中。

http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/system/LoaderContext.html#applicationDomain

var lc:LoaderContext = new LoaderContext();
lc.applicationDomain = ApplicationDomain.currentDomain;

loader.load(new URLRequest("Singleton.swf"), lc);

您会看到,通常在加载SWF时,它会加载到自己的应用程序域中。但这使得无法在加载的SWF上强制执行单例模式,因为类的每个实例都可以存在于自己的应用程序域中(因此最终可能会有多个实例)。因此,如果要在多个SWF加载中强制执行此操作,则需要将其加载到加载SWF的应用程序域中。

答案 1 :(得分:1)

如果您的问题是“一旦Event.COMPLETE从引入swf的Loader中解雇了,我应该如何引用Singleton?”,那么您可以使用:

var Singleton:Object = _loader.contentLoaderInfo.applicationDomain.getDefinition('Singleton');

但是,我不确定你不想使用“var”引用是什么意思。

另一方面,全局变量很可能比API的Singleton类更好。

package myPackage
{
    public var myGlobal:MyGlobal = new MyGlobal();
}

您可以使用myPackage.myGlobal

进行访问