【问题标题】:Why isn't stage global?为什么舞台不是全球性的?
【发布时间】:2011-09-21 06:50:35
【问题描述】:

我想知道在每个对象中创建舞台非静态引用而不是使其成为全局对象有什么好处。因此,我只有解除引用 null 的问题。但是,一定有 Adob​​e 工作人员这样做的原因。那么,有人可以向我解释这种行为吗?当我使用类似下面的代码并在需要舞台的任何地方使用 gStage 时,我会遇到什么问题?

package
{
    public var gStage: Stage;
    public class Main extends Sprite;
    {
        public function Main()
        {
            if (stage)
                init();
            else
                stage.addEventListener (Event.ADDED_TO_STAGE, init);
        }
        public static function init(): void
        {
            stage.removeEventListener (Event.ADDED_TO_STAGE, init);
            gStage = stage;
        }
    }
}

顺便说一句,为什么在我见过的每个 AS3 代码示例中 Main 都扩展了 Sprite?

【问题讨论】:

  • 为什么应该舞台是全球性的?
  • 这会抛出一个空指针异常。首先确保 stage == null 然后在其上调用函数。
  • 全局变量(通常)打破了面向对象的编程范式。只需将所有内容放在同一个舞台上,并使用 Event 对象进行通信。扩展 Sprite 的名为 Main 的示例肯定是文档/控制器类,它们已经被添加并可以访问舞台。您应该阅读一些有关 AS3 的书籍 - 要了解的内容很多,而通过谷歌搜索答案并不是理解该语言的明智方法。

标签: actionscript-3 global-variables stage


【解决方案1】:

虽然每个 Flash 影片通常都有一个用于绘制可见显示对象的舞台,但在 AIR 应用程序中不只有一个“全局”舞台;每个窗口都有自己的舞台,因此每个窗口对象都必须有自己的实例引用到自己的舞台。在这种情况下,制作单个静态全局舞台对象是不正确的——如果 AIR 应用程序需要多个窗口怎么办?

【讨论】:

  • AIR 就是一个很好的例子。可能有用的更多细节:舞台属性仅在显示对象上可用。每个显示对象都包含对舞台的引用,但如果显示对象不在显示列表中(例如,实际附加到舞台),它将为空。与显示对象的“根”属性相同。
【解决方案2】:

上面有人问,“为什么舞台应该是全球性的?” 答:我不认为它应该是全局的,但这里有一个简单的用例,全局访问舞台非常有用: 在将 DisplayObject 和/或其视觉资产添加到显示列表之前,查找可用的像素来布局(位置、大小)

有时我的布局类不扩展 DisplayObject 并获取对 DisplayObjects 的引用以布局 之前 DisplayObject 已添加到显示列表 - 因此没有 stage 属于它自己的财产。 使用下面的方法,在主文档类具有 stage 属性并调用后,我总是可以随时知道当前可用像素 GlobalReference.global.stage = stage;

var screenWidth : uint = GlobalReference.global.stage.stageWidth;
var screenHeight : uint = GlobalReference.global.stage.stageHeight;

!!警告 !!全局变量很危险且容易误用

我添加了对“全局”对象的引用(非常仔细和深思熟虑),以便我可以从任何类访问它们——特别是能够在闭包或匿名函数中访问它。闭包不需要调用静态 getter,因为它们已经在全局范围内。

package com.appcloud9.utils
{
    public class GlobalReference
    {
        public static function get global() : Object
        {
            // may be superstition, but I *think* that assigning the function
            // to a var is better for garbage collection later
            var getGlobal : Function = function() : Object
            {
                return this;
            };
            return getGlobal();
        }
    }
}

// usage examples :

// I call this in my main document class on the Event.EXIT_FRAME event :
GlobalReference.global.stage = stage;

// later in a closure
var signalLightsOut = new Signal();
signalLightsOut.add( function() : void
{
    trace( stage );                        // [object Stage]
} );

// later in a constructor - before the class has a stage of it's own
public function MyConstructor()
{
    trace( stage );                        // null
    trace( GlobalReference.global.stage ); // [object Stage]
    /* note : it is usually best and fully adequate to wait until a class extending
        DisplayObject has its own stage : after Event.ADDED_TO_STAGE and then
        Event.EXIT_FRAME it is guaranteed. */
}

【讨论】:

    猜你喜欢
    • 2016-05-12
    • 1970-01-01
    • 2022-07-18
    • 2018-03-22
    • 1970-01-01
    • 2016-06-20
    • 2010-09-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多