Почему не глобальный этап?
Интересно, какие преимущества дает создание нестатической ссылки на этапе в каждом объекте вместо того, чтобы сделать его глобальным. Из-за этого у меня только проблемы с разыменованием 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 ответа
Хотя в каждом Flash-фильме обычно есть один этап, на котором рисуются видимые экранные объекты, в приложениях AIR не существует только одного "глобального" этапа; каждое окно имеет свою собственную стадию, и, следовательно, каждый объект окна должен иметь свою собственную ссылку на экземпляр на свою собственную стадию. В этом случае было бы неправильно создавать один статический объект глобальной сцены. Что если приложению AIR требуется несколько окон?
Кто-то спросил выше: "Почему сцена должна быть глобальной?" 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. */
}