メインタイムラインで GLOBAL VAR を宣言しようとしています。
次に、外部からロードされた別の SWF からその GLOBAL VAR にアクセスする必要があります。
質問:
メイン タイムラインでグローバル変数を作成するにはどうすればよいですか?
外部からロードされた swf ファイルでその var にアクセスするにはどうすればよいですか?
メインタイムラインで GLOBAL VAR を宣言しようとしています。
次に、外部からロードされた別の SWF からその GLOBAL VAR にアクセスする必要があります。
質問:
メイン タイムラインでグローバル変数を作成するにはどうすればよいですか?
外部からロードされた swf ファイルでその var にアクセスするにはどうすればよいですか?
まず、グローバル/静的状態を使用しない でください。あなたの状況では、これはさらに当てはまります。なぜなら、シングルトンはさまざまなアプリケーションドメインにまたがる厄介な問題だからです。
代わりに、Dependency Injectionと呼ばれるものを使用する必要があります。小さな SWFS を飢えた孤児と考えてください。それらが読み込まれると、メインの SWF に駆け寄ってそのポケットを選ぶことはありません。代わりに、メインの SWF は寛大に彼らの小さな手にお金を押し付けます。
では、これを実現するにはどうすればよいでしょうか。1 つの方法は、Document クラスへの参照をメインの swf にコンパイルしてから、クラスが公開する変数を設定することです。ただし、これはかなり重くなる可能性があり、実際には必要ありません。
代わりに、孤児の「アイデア」を定義するInterfaceと呼ばれるものを書くことができます。
次のようになります。
public interface IOrphan {
function get alms():Number;
function set alms(value:Number):void;
}
インターフェイスでは getter と setter を使用する必要があることに注意してください。これらを使用してバニラ変数を定義することはできません。ただし、実際の Orphan ではうまくいくでしょう。
public class Oliver implements IOrphan {
private var _alms:Number;
private var _totalAlms:Number;
public var tf:TextField;//put this on stage and allow Flash to populate automatically
public function get alms():Number {
return _alms;
}
public function set alms (value:Number):void {
_alms = value;
_totalAlms += _alms;
updateAlmsMessage();
}
private function updateAlmsMessage():void {
tf.text = 'That was a donation of ' + _alms + '.\n'
'I now have ' _totalAlms + '.\n'
'Please, sir, can I have some more?';
}
}
あとは、ロード時にその変数を設定するだけです。これを行うにはいくつかの方法があります。たとえば、IOliver がロードされるステージを監視するか、それについてより直接的に伝えることができます。
private function loadSwf(url:String):void {
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
var request:URLRequest = new URLRequest(url);
loader.load(request);
addChild(loader);
}
private function completeHandler(e:Event):void {
((e.target as LoaderInfo).content as IOrphan).alms = .25;
}
これらが一度だけ設定したい変数であり、決して変更されない場合は、静的定数を保持するクラスを作成するだけです。
package
{
public class Env
{
public static const WHATEVER:String = "Whatever!";
public function Env()
{}
}
}
次に、次のようにプログラムの後半でそれらにアクセスできます。
trace(Env.WHATEVER);
ただし、変更可能なグローバル変数が必要な場合は、シングルトンクラスを使用してこれを処理するのが好きです。
package
{
import flash.events.EventDispatcher;
public class Control extends EventDispatcher
{
//---------------------------------------
// PRIVATE & PROTECTED INSTANCE VARIABLES
//---------------------------------------
private static var _instance:Control;
//---------------------------------------
// PUBLIC VARIABLES
//---------------------------------------
public var whatever:String = "Whatever";
//---------------------------------------
// PUBLIC METHODS
//---------------------------------------
public static function get instance():Control
{
return initialize();
}
public static function initialize():Control
{
if (_instance == null)
{
_instance = new Control();
}
return _instance;
}
//---------------------------------------
// CONSTRUCTOR
//---------------------------------------
public function Control()
{
super();
if (_instance != null)
{
throw new Error("Error:Control already initialised.");
}
if (_instance == null)
{
_instance = this;
}
}
}
}
ここでの違いは、シングルトンの内部に到達する前に、シングルトンのインスタンスを取得する必要があることです。少しこんな感じになります。
private var _control:Control = Control.instance;
// Reading a global variable
trace(_control.whatever);
// Change a global variable
_control.whatever = "Foobar!";
したがって、「何でも」を変更すると、ロードされたすべてのSWFに対してその変数が変更されます。本当に気になりたい場合は、単純なパブリック変数ではなく、シングルトンでゲッター/セッターを使用できます。