【问题标题】:AS3: Singleton class vs LocalConnection classAS3:Singleton 类与 LocalConnection 类
【发布时间】:2010-08-14 23:29:01
【问题描述】:

我有一个加载 2 个 SWF 的 Main 类(加载器和查看器,还有文档类)。他们需要与内容共享一个双缓冲区,当然,由加载器填充并由查看器显示

我正在考虑使用 LocalConnection 类,但在 PatrickS 的建议之后,我现在正在评估单例类的可能性。我从未在 AS 中使用过这种模式,必须承认我对它有偏见。但在这种特殊情况下,我想它会很有用。顺便说一句,在 gskinner 博客 2 implementations examples 中阅读有点惊讶。所以,我非常感谢你的观点,因为我知道这个主题是一场无休止的战争,就像 Mac 与 PC 之间的战争

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

我担心的另一个问题是内存泄漏

提前致谢

【问题讨论】:

    标签: actionscript-3 air singleton localconnection


    【解决方案1】:

    我个人会避免使用 Singleton,因为它会定期实施。但是,拥有此缓冲区对象的单个实例是有意义的。所以在这种情况下我要做的是让你的 Main 类创建这个对象。加载查看器时,将这个对象传递给它。然后对装载机做同样的事情。现在,您的两个 swf 共享一个可以用来通信的公共对象。然后,您可以在其上调用函数并根据需要使其调度事件(扩展 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));
            }
        }
    
    }
    

    基本上,当您同时加载查看器和加载器 swfs 时,您会传递这个公共对象的一个​​实例。然后你注册监听一个 INIT 方法:这将告诉 loader 和 viewer 一切都已经设置好了。所以此时你可以开始从你的查看器或加载器向对方发送消息(你可以通过事件调度来实现);基本上在公共对象中创建一个方法来为你做这件事,或者直接在公共对象上调用 dispatchEvent 。

    【讨论】:

    • JP: 非常感谢您的帮助,您的代码看起来很干净且易于实现,所以我会尝试一下(只是一件小事,您似乎忘记在 Main.xml 中导入 CommonObject 类。作为,不是吗?)。还有一个问题,当你说我个人会避免使用单例时,因为它“定期”实施,你到底是什么意思?糟糕的代码,如果不是在语言中本地实现的设计模式,就不要使用它,...? Grant Skinner 的博客、Apple AS3 文档或本网站中的实现看起来非常简单
    • @hsands。别客气。如果类在同一个包中,则不需要导入。由于这只是测试代码,我将所有内容都放在“全局”包中。但是,在实际项目中,您可能希望将代码放在一个包中以避免名称冲突。
    • @hsands。关于单例:有时只有一个实例是有意义的。我不喜欢该模式如何尝试强制执行此操作:拥有一个创建/检索此实例的静态访问器。我宁愿在其他地方创建这个实例并传递它(有点像依赖注入)。因为,一方面,如果您的对象需要带参数,这种模式会变得不方便。此外,如果您有多个 appDomain,则最终可能会出现多个实例(当您阅读代码时这不会那么明显)。如果您需要创建另一个实例,那么您就有麻烦了。
    • @JPC:我已经根据您的建议实施了一个版本,并且运行良好。现在,我想通过加载器和查看器中的侦听器实现一些在 CommonObject 中调度的海关事件。你能指出我正确的方向吗,也许是一个例子/指南/教程?再次感谢您的帮助
    • @hsands。没问题。查看此内容以了解自定义事件的介绍。 learningactionscript3.com/2008/11/11/…。扩展Event 相当简单(不要忘记覆盖clone() 方法!),所以我想看看一些示例代码,你就会明白了。这只是一点点语法(剩下的就是设计你想要传递的数据,这取决于你)。但是,如果您发现一些问题,请不要犹豫,提出一个新问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-26
    • 2019-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多