2

そのため、「MyBigAwesomeClass」というクラスのオブジェクトを子から親に渡したいという状況があります。クラス定義を親と子の両方にインポートします。

ここで、親の場所に相対的な場所から子swfをロードすると、すべて問題ありませんが、完全な絶対パスを使用してロードすると、親と子の「BigAwesomeClass」の定義が処理されます。異なるものとして、タイプ'BigAwesomeClass'のオブジェクトを親クラスの同じオブジェクトに割り当てることはできません。

私は完全に困惑しており、このコードの使用を含め、ApplicationDomainsに頭を悩ませてきました

loader.contentLoaderInfo.addEventListener(Event.COMPLETE,swfLoaded);
var context:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain); 
loader.load(new URLRequest(_file.url),context);

まったく役に立たない。これを修正するために何ができるかについてのアイデアはありますか?

前もって感謝します

4

4 に答える 4

1

Adobe のドキュメント ( Loader#securityDomain ) によると:

インポートの読み込みが成功するためには、読み込まれた SWF ファイルのサーバーに、読み込み中の SWF ファイルのドメインを信頼するポリシー ファイルが必要です。

トリックは、swf をロードするときにクロスドメイン ファイルをチェックするように Loader に指示することですtrueLoaderContextたとえば、.

var request:URLRequest = new URLRequest(_file.url);
var context:LoaderContext = new LoaderContext(true, null, SecurityDomain.currentDomain);
var loader:Loader = new Loader();
loader.load(request, context);

付随する cross-domain.xml は、子 SWF と同じ場所、またはその親フォルダーの 1 つに配置する必要があります。Adobe のドキュメントによると、制限のないクロスドメイン ファイルは次のとおりです。

<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM
"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
    <site-control permitted-cross-domain-policies="all"/>
    <allow-access-from domain="*" secure="false"/>
    <allow-http-request-headers-from domain="*" headers="*" secure="false"/>
</cross-domain-policy>

これを簡単にするもう 1 つの方法は、クラスの代わりにインターフェイスを渡すことです。これにより、競合するコードを効果的にバイパスできます。子は実行時にデフォルトで親クラスからインターフェイスを継承するため、これは機能します ( Loader#applicationDomainポイント #1 を参照)。子クラスは、オブジェクトがインターフェイスに準拠している限り、各オブジェクトの独自のバージョンを安全にインスタンス化できます。例えば:

var applicationDomain:ApplicationDomain = loader.contextLoaderInfo.applicationDomain;
var classDefinition:Class = applicationDomain.getDefinition("MyBigAwesomeClass") as class;
var instance:IMyBigAwesomeInterface = new classDefinition() as IMyByAwesomeInterface;

MyBigAwesomeClass の定義は次のようになります。

public class MyBigAwesomeClass implements IMyBigAwesomeInterface 
{
    ...
}
于 2011-08-13T14:19:30.930 に答える
1

サンドボックスの問題であることがわかりました。インストーラーの一部ではないファイルは別のセキュリティ サンドボックスに配置されます。これらのファイルは別のサンドボックスに存在するため、子は親にインポートされたときに親の定義を継承せず、ApplicationDomain互換性のない 2 つの別個の定義が存在します。残念ながら、これを直接解決する方法はないようです。Adobe はSandBoxBridgeを介したサンドボックス間の通信を許可していますが、そのためにはオブジェクト型を使用する必要があり、全体の目的が無効になります。私が知る限り、2 つの異なるサンドボックスのクラスがまったく同じであっても、互換性を持つ方法はありません。オブジェクトの厳密な型指定がないという痛ましい世界が戻ってきたのではないでしょうか。

于 2011-08-14T12:20:38.787 に答える
0

問題はおそらく親と子のアプリケーション ドメインに関係していることに同意しますが、より正確に答えるために、親と子の間で共有したいクラスの使用例がいくつかあるとよいでしょう。子供。

理論的には、子に対してもクラスが定義されていれば、問題は回避できるようです...これは、私の意見では、子をどこからロードしても機能するはずの非常に基本的な例です。

パッケージ com.example.test
{
   public class Parent は Sprite を拡張します
   {
      private var child:Child;
      private var shared:SharedClass = new SharedClass();

      パブリック関数 Parent()
      {
         loadChild();
      }

      プライベート関数 loadChild():void
      {
         //ロード処理
      }

      プライベート関数 loadComplete(event:Event):void
      {
          child = event.currentTarget.content as Child;

          if( 子 != null )   
             共有 = child.shared;
          // イベントなどを削除...
      }
   }
}

パッケージ com.example.test
{
   public class Child extends Sprite
   {
      // ここでは public var を使用していますが、getter を使用することもできます...
      public var shared:SharedClass;

      パブリック関数 Child()
      {
            共有 = 新しい SharedClass();
      }
   }
}

パッケージ com.example.test
{
   パブリック クラス SharedClass
   {
      パブリック関数 SharedClass()
      {
           trace('共有クラスからこんにちは');
      }
   }
}
于 2011-08-13T16:50:33.757 に答える
0

1 つのオプションは、子クラスにメソッドを実装して、独自の applicationDomain を使用してクラスのインスタンスを返すことです。次に例を示します。

public class Child extends Sprite implements IMyBigAwesomeClassLoader
{
   public function getMyByigAwesomeClass():IMyBigAwesomeClass
   {
       var classDefinition:Class = applicationDomain.getDefinition("MyBigAwesomeClass");
       var instance:IMyBigAwesomeClass = new classDefinition() as IMyBigAwesomeClass;
       return instance;
   }
}

は次のIMyBigAwesomeClassLoaderようになります。

public interface IMyBigAwesomeClass 
{
  function getMyBigAwesomeClass():IMyBigAwesomeClass;
}

親クリップは、これを使用して、ロード時に子からインスタンスを取得します。

public function loadCompleteHandler(event:Event):void
{
  var myBigAwesomeClassLoader:IMyBigAwesomeClassLoader = (event.target as Loader).content as IMyBigAwesomeClass;
  myBigAwesomeClass = myBigAwesomeClassLoader.getMyBigAwesomeClass();
}

ここでインターフェイスを使用する理由は、クラス定義をその実装から切り離すためです。親 SWF と子 SWF のクラスが同じ名前であっても、Flash はそれらを異なるクラスとして扱います。インターフェイスは、Flash に、それらが異なっていても同じように使用できることを伝えます。

Flash は静的型付けを使用します。つまり、一度定義されたクラスは変更されず、あるクラス定義が別のクラス定義で上書きされることはありません。そのため、同じ名前のクラスが 2 つある場合はgetDefinition、競合する名前を解決するために を使用する必要があります。このように複雑さが増すのを避けたい場合は、親 SWF と子 SWF のクラスに異なる名前または名前空間を使用できます。

于 2011-08-14T10:32:29.573 に答える