プロジェクトが複雑になった時、SWFを複数に分割することがあります。たとえばボタンやエラーパネルのような共通の素材を別SWFにして使い回したり、Progressionのpreloaderのように役割をわけたり、といった場合があります。

このように同じ要素を一元化すると開発上とても効率がいいのですが、実はちょっとだけ問題があります。

複数のSWFにまたがって同じクラスファイルを使うときは、実際はそれぞれのSWFに同じクラス定義が存在しており、実行時には同じパッケージ内の同名クラスがあればロードした親クラスの方が優先されます。

内容が全く一緒であれば問題はありませんが、開発の途中でSWFごとに微妙に違うバージョンが混在した場合、定義がちがったり挙動が変わってしまってうまく動かなくなることがあります。

これに気をつけて開発するコツを少しまとめようと思います。

共有する方法

まず前提として共有する方法をまとめてみます。

もっとも簡単なのは共有ようの変数クラスを作って橋渡しする方法です。AS2時代のグローバル変数のようにどちらからもアクセスできる変数を用意します。

はじめは親SWFでインスタンスを生成して、それを子SWFでも使えるようにするパターン。

//■親SWF
//共有したいオブジェクト(例:エラーパネル)
public class ErrorPanel extends Sprite{
}

//共有用の変数クラス
public class GlobalVariables{
    public static var errorPanel:ErrorPanel;
}
// 親SWFでの準備
GlobalVariables.errorPanel = new ErrorPanel();

//--------
//■子SWF
//利用時
var errorPanel:ErrorPanel = GlobalVariables.errorPanel;
addChild( errorPanel ); // 親クラス経由じゃない=値がない とエラー

 もうひとつはClassオブジェクト自体を共有(または取得)して子SWF側で生成するパターン。

//■親SWF
//共有用の変数クラス
public class GlobalVariables{
    public static var errorPanelClass:Class;
}
// 親SWFでの準備
GlobalVariables.errorPanelClass = ErrorPanel;

//--------
//■子SWF
//利用時
var errorPanel:ErrorPanel = new GlobalVariables.errorPanelClass as ErrorPanel;
addChild( errorPanel ); // 親クラス経由じゃない=値がない とエラー

 これだと自由に子SWF側でインスタンスを増やすことができます。ただしキャストする型がわからないか、暗黙の了解でつじつまをあわせるという若干の無理が生じます。これは自分のなかでやる分にはいいですが、複数人での開発や、外部の開発者にライブラリとして提供する場合などはあまり望ましくありません。

参考までにクラス自体を取得する方法はもうひとつあります。クラスオブジェクトがロードされていてパッケージ名からの完全修飾名がわかる場合に限りますが、flash.utils.getDefinitionByName で文字列からクラスを取り出すことができます。

var klass:Class = getDefinitionByName("com.kayac.ErrorPanel") as Class;

var errorPanel:ErrorPanel = new klass() as ErrorPanel;
addChild( errorPanel );

クラスを上手に分離する方法

次回は子SWFにErrorPanelクラスを読み込ませない方法を考えてみます。その2に続きます

 

HTML5飯