Actionscript 3 AS3:单例类与本地连接类

Actionscript 3 AS3:单例类与本地连接类,actionscript-3,air,singleton,localconnection,Actionscript 3,Air,Singleton,Localconnection,我有一个主类加载2 SWF(加载器和查看器,也有文档类)。当然,它们需要与内容共享一个双缓冲区,由加载程序填充,由查看器显示 我原打算使用LocalConnection类,但在Patrick提出建议后,现在我正在评估使用Singleton类的可能性。我从未在AS中使用过这种模式,必须承认我对它有相当大的偏见。但在这种情况下,我想它会有用的。顺便说一句,读到gskinner博客2实现示例时有点惊讶。所以,我非常欣赏你的观点,因为我知道这是一场无穷无尽的战争,就像Mac和PC之间的战争一样 考虑到:

我有一个主类加载2 SWF(加载器和查看器,也有文档类)。当然,它们需要与内容共享一个双缓冲区,由加载程序填充,由查看器显示

我原打算使用LocalConnection类,但在Patrick提出建议后,现在我正在评估使用Singleton类的可能性。我从未在AS中使用过这种模式,必须承认我对它有相当大的偏见。但在这种情况下,我想它会有用的。顺便说一句,读到gskinner博客2实现示例时有点惊讶。所以,我非常欣赏你的观点,因为我知道这是一场无穷无尽的战争,就像Mac和PC之间的战争一样

考虑到: 1.AIR desktop应用程序在高端Windows PC上几个月内全天候运行。无需用户交互 2.高性能代码是必须的,因为加载的内容是全高清图像

我的另一个担忧是内存泄漏


提前感谢

我个人会避免单身,因为它是定期实施的。但是,拥有此缓冲区对象的单个实例是有意义的。所以在这种情况下我要做的是让你的主类创建这个对象。加载查看器时,将其传递给此对象。然后对加载程序执行同样的操作。现在,您的两个主权财富基金共享一个可用于通信的公共对象。然后,您可以对其调用函数,并使其根据需要分派事件(扩展EventDispatcher或实现IEventDispatcher)。或者,如果您愿意,您可以注册回调(应该快一点,但不确定这是否会产生很大的影响)

编辑

看看你的另一个问题,我认为你的问题与获取正确的加载器和将数据传递给加载的内容有关。这里有一个如何实现我上面提到的要点

PhotoLoader.swf:

package  {
import flash.display.Sprite;
import flash.events.Event;

public class PhotoLoader extends Sprite {

    private var _commonObject:CommonObject;

    public function PhotoLoader() {

    }

    public function setCommonObject(commonObject:CommonObject):void {
        trace("PhotoLoader::setCommonObject", commonObject);
        _commonObject = commonObject;
        _commonObject.addEventListener(Event.INIT,handleInit);
    }

    private function handleInit(e:Event):void {
        trace("PhotoLoader::handleInit");
    }

}

} 
PhotoViewer.swf:

package  {
    import flash.display.Sprite;
    import flash.events.Event;

    public class PhotoViewer extends Sprite {

        private var _commonObject:CommonObject;

        public function PhotoViewer() {

        }

        public function setCommonObject(commonObject:CommonObject):void {
            trace("PhotoLoader::setCommonObject", commonObject);
            _commonObject = commonObject;
            _commonObject.addEventListener(Event.INIT,handleInit);
        }

        private function handleInit(e:Event):void {
            trace("PhotoViewer::handleInit");
        }

    }

}
Main.swf

package {
    import flash.display.Loader;
    import flash.display.LoaderInfo;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.net.URLRequest;
    import flash.system.ApplicationDomain;
    import flash.system.LoaderContext;

    public class Main extends Sprite {

        private var _photoLoader:PhotoLoader;
        private var _photoViewer:PhotoViewer;
        private var _commonObject:CommonObject;

        private var _viewerLoader:Loader;
        private var _loaderLoader:Loader;

        private var _count:int = 0;

        public function Main():void {
            _commonObject = new CommonObject();
            loadSwfs();

        }

        private function loadSwfs():void {

            _viewerLoader = new Loader();
            _viewerLoader.contentLoaderInfo.addEventListener(Event.INIT,handleInit);
            _viewerLoader.load(new URLRequest("PhotoViewer.swf"));

            _loaderLoader = new Loader();
            _loaderLoader.contentLoaderInfo.addEventListener(Event.INIT,handleInit);
            _loaderLoader.load(new URLRequest("PhotoLoader.swf"));

        }

        private function handleInit(e:Event):void {
            trace("handleInit");
            var loader:Loader = (e.target as LoaderInfo).loader;
            switch(loader) {
                case _viewerLoader:
                    _photoViewer = _viewerLoader.content as PhotoViewer; 
                    _photoViewer.setCommonObject(_commonObject);
                    _count++;
                    break;
                case _loaderLoader:
                    _photoLoader = _loaderLoader.content as PhotoLoader; 
                    _photoLoader.setCommonObject(_commonObject);
                    _count++;
                    break;
            }
            if(_count == 2) { 
                _commonObject.init();
            }

        }


    }

}
以及3 swf共享的公共对象:

package  {
    import flash.events.Event;
    import flash.events.EventDispatcher;

    public class CommonObject extends EventDispatcher {

        public function CommonObject() {

        }

        public function init():void {
            dispatchEvent(new Event(Event.INIT));
        }
    }

}

基本上,当您同时加载查看器和加载程序SWF时,您会传递此公共对象的一个实例。然后您注册以侦听INIT方法:这将告诉加载程序和查看器一切都已设置好。因此,此时您可以开始从查看器或加载程序向另一方发送消息(您可以通过事件调度来实现);基本上,在公共对象中创建一个方法来为您执行此操作,或者直接在公共对象上调用dispatchEvent

JP:非常感谢您的帮助,您的代码看起来干净且易于实现,因此,我将尝试一下(只是一件小事,您似乎忘记了在Main.as中导入CommonObject类,否?)。还有一个问题,当你说我会避免单身,就个人而言,因为它“定期”实施,你到底是什么意思?糟糕的代码,如果设计模式不是在语言中本机实现的,就永远不要使用它。。。?在格兰特·斯金纳的博客、苹果AS3文档或这个网站上的实现看起来很不错straightforward@hsands. 不客气。如果类在同一个包中,则不需要导入。因为这只是测试代码,所以我将所有内容都放在“全局”包中。不过,在实际项目中,您可能希望将代码放入包中以避免名称冲突。@hsands。Re singleton:有时候只有一个实例是有意义的。我不喜欢该模式试图强制执行此操作的方式:使用创建/检索此实例的静态访问。我宁愿在其他地方创建这个实例并传递它(有点像依赖注入)。因为,首先,如果您的对象需要获取参数,则此模式将变得不方便。此外,如果您有多个appDomain,那么最终可能会有多个实例(在阅读代码时,这一点不会太明显)。如果您需要创建另一个实例,那么您就有麻烦了。@JPC:我已经根据您的建议将一个版本付诸实施,它运行良好。现在,我想在loader&viewer中使用侦听器在CommonObject中实现一些定制事件。你能给我指出正确的方向吗,也许是一个例子/指南/教程?再次感谢您的支持help@hsands. 没问题。查看此文件以了解自定义事件的介绍。扩展
Event
相当简单(不要忘记重写
clone()
方法!),因此我想看看一些示例代码,您就会明白了。这只是一点点语法(剩下的就是设计你想要传递什么样的数据,这取决于你自己)。如果你发现了一些麻烦,不要犹豫,打开一个新的问题。