Почему не глобальный этап? - PullRequest
1 голос
/ 23 июня 2011

Интересно, какую выгоду дает создание в каждом объекте нестатической ссылки вместо того, чтобы делать ее глобальной. Из-за этого у меня только проблемы с разыменованием null. Но должен быть случай, почему команда Adobe сделала это таким образом. Итак, кто-то может объяснить мне такое поведение? И какие проблемы могут возникнуть, когда я использую что-то вроде следующего кода и использую 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?

Ответы [ 2 ]

5 голосов
/ 23 июня 2011

Несмотря на то, что в каждом видеоролике Flash обычно есть один этап, на котором рисуются видимые экранные объекты, в приложениях AIR не существует только одного «глобального» этапа; каждое окно имеет свою собственную стадию, и, следовательно, каждый объект окна должен иметь свою собственную ссылку на экземпляр на свою собственную стадию. В этом случае было бы неправильно создавать один статический объект глобальной сцены - что если приложению AIR требуется несколько окон?

0 голосов
/ 19 декабря 2012

Кто-то спросил выше: «Почему сцена должна быть глобальной?»A: Я не думаю, что должно быть глобальным, но вот простой пример использования, когда глобальный доступ к рабочей области очень полезен: поиск доступных пикселей для размещения (положение, размер) объекта DisplayObject и / илиили его визуальные активы перед добавлением в список отображения .

У меня иногда есть классы макетов, которые не расширяются DisplayObject и не получают ссылки на DisplayObjects на макет перед DisplayObject был добавлен в список отображения - и поэтому у него пока нет собственного свойства stage.Используя мой метод ниже, я всегда могу узнать текущие доступные пиксели в любое время после того, как основной класс документа имеет свойство stage и вызывает GlobalReference.global.stage = stage;

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

!!ВНИМАНИЕ !!глобальные переменные опасны и их легко неправильно использовать

Я добавляю ссылки на «глобальный» объект (очень тщательно и продуманно), чтобы я мог получить к ним доступ из любого класса - и, в частности, иметь возможность доступа к нему в закрытом или анонимномфункция.Замыканиям не нужно вызывать статический метод получения, потому что они уже находятся в глобальной области видимости.

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. */
}
...