これに似た2つのローダーを使用して2つのswfsをロードするクラスがあります(新しいApplicationDomainに注意してください)。
var child1Loader:Loader = new Loader()
child1Loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onChild1Complete)
child1Loader.load(new URLRequest("http://mywebsite.com/assets/load_test/Child1Factory.swf?" + Math.random()), new LoaderContext(false, new ApplicationDomain(ApplicationDomain.currentDomain)))
ロードされたswfsは、実際にはファクトリです。
public class Child1Factory extends Sprite
{
public function Child1Factory() {}
public function getChild1():Child1 {
return new Child1()
}
}
両方のswfsがロードされたら、次のように、child1とchild2をステージに追加します。
var child1:MovieClip = child1Factory.getChild1()
var child2:MovieClip = child2Factory.getChild2()
addChild(child1)
addChild(child2)
Child1とchild2は非常によく似ていますが、同一ではありません。Child1は次のようになります(ADDED_TO_STAGEリスナーに注意してください):
public class Child1 extends MovieClip
{
public function Child1()
{
Security.allowDomain("*")
if (stage) onAddedToStage(null)
else addEventListener(Event.ADDED_TO_STAGE, onAddedToStage)
}
private function onAddedToStage(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage)
addChild(new MC_CircleGroup())
runChild1Test()
}
private function runChild1Test():void {
var circles:Array = findChildrenOfType(MC_Circle, this)
if (circles.length == 0) {
throw new Error("Oh no!")
}
}
private function findChildrenOfType(type:Class, container:DisplayObjectContainer):Array {
var toReturn:Array = []
for (var childIndex:int = 0; childIndex < container.numChildren; childIndex++) {
var child:DisplayObject = container.getChildAt(childIndex)
if (child is type) {
toReturn.push(child)
} else if (child is DisplayObjectContainer) {
toReturn = toReturn.concat(findChildrenOfType(type, child as DisplayObjectContainer))
}
}
return toReturn
}
}
そして、child2は、円の正方形を読み取ることを除いて同様です。両方のクラスには、関連するMC_SquareGroupまたはMC_CircleGroupムービークリップを含む異なるswcsがあります。これらには、タイプMC_SquareまたはMC_Circleの4つの子があります。findChildrenOfType関数は通常、これら4つのインスタンスの配列を返します。
エラー「Onno!」アプリケーションを実行する5回ごとに約1回スローされます。誰かが今なぜですか?それとも、今でも回避策を持っている人はいますか?
いくつかのメモ:
1.)エラーは、インターネットまたはローカルネットワークを介してswfsをロードした場合にのみスローされます。swfsが同じコンピューター上にある場合はスローされません。
2.)child1をロードしますが、child2またはvisavirsaはロードしません。エラーは発生しません。
3.)エラーが発生した場合、私のデバッガーによると、MC_CircleGroupの子はMC_CircleではなくMovieClipタイプです。
4.)アプリケーションを実行するたびにエラーがスローされるわけではありません。それは数回だけです。一貫してエラーを取得するには、両方のswfsがロードされたら、ローダーを再度呼び出してロードをループする必要があります。
リクエストに応じて完全なソースコードを利用できます。
ありがとう!ティム
アップデート
ローダーファイルの完全なコードは次のようになります。
public class Main extends Sprite
{
private var child1Factory:Object;
private var child1Loaded:Boolean = false;
private var child2Factory:Object;
private var child2Loaded:Boolean = false;
public function Main():void
{
Security.allowDomain("*")
if (stage) loadChildren();
else addEventListener(Event.ADDED_TO_STAGE, loadChildren);
}
private function loadChildren(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, loadChildren);
child1Loaded = false
child2Loaded = false
var child1Loader:Loader = new Loader()
child1Loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onChild1Complete)
child1Loader.load(new URLRequest("http://mywebsite.com/assets/load_test/Child1Factory.swf?" + Math.random()), new LoaderContext(false, new ApplicationDomain(ApplicationDomain.currentDomain)))
var child2Loader:Loader = new Loader()
child2Loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onChild2Complete)
child2Loader.load(new URLRequest("http://mywebsite.com/assets/load_test/Child2Factory.swf?" + Math.random()), new LoaderContext(false, new ApplicationDomain(ApplicationDomain.currentDomain)))
}
private function onChild1Complete(e:Event):void {
child1Factory = e.currentTarget.content
child1Loaded = true
if (child2Loaded) {
onLoadComplete()
}
}
private function onChild2Complete(e:Event):void {
child2Factory = e.currentTarget.content
child2Loaded = true
if (child1Loaded) {
onLoadComplete()
}
}
private function onLoadComplete():void {
var child1:MovieClip = child1Factory.getChild1()
var child2:MovieClip = child2Factory.getChild2()
addChild(child1)
addChild(child2)
loadChildren(null)
}
}
UPDATE 2 OK、これはさらに奇妙になっています。手紙の@DavidMearに続いて、子がonChildXComplete関数に追加され、突然壊れることが少なくなるように更新しました。それでも非常にまれに壊れます:
public class Main extends Sprite
{
private var child1Factory:Object;
private var child1Loaded:Boolean = false;
private var child2Factory:Object;
private var child2Loaded:Boolean = false;
public function Main():void
{
Security.allowDomain("*")
if (stage) loadChildren();
else addEventListener(Event.ADDED_TO_STAGE, loadChildren);
}
private function loadChildren(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, loadChildren);
child1Loaded = false
child2Loaded = false
var child1Loader:Loader = new Loader()
child1Loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onChild1Complete)
child1Loader.load(new URLRequest("http://mywebsite.com/assets/load_test/Child1Factory.swf?" + Math.random()), new LoaderContext(false, new ApplicationDomain(ApplicationDomain.currentDomain)))
var child2Loader:Loader = new Loader()
child2Loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onChild2Complete)
child2Loader.load(new URLRequest("http://mywebsite.com/assets/load_test/Child2Factory.swf?" + Math.random()), new LoaderContext(false, new ApplicationDomain(ApplicationDomain.currentDomain)))
}
private function onChild1Complete(e:Event):void {
child1Factory = e.currentTarget.content
child1Loaded = true
var child1:MovieClip = child1Factory.getChild1()
addChild(child1)
if (child2Loaded) {
onLoadComplete()
}
}
private function onChild2Complete(e:Event):void {
child2Factory = e.currentTarget.content
child2Loaded = true
var child2:MovieClip = child2Factory.getChild2()
addChild(child2)
if (child1Loaded) {
onLoadComplete()
}
}
private function onLoadComplete():void {
loadChildren(null)
}
}
更新3
このコードは、元のトレースとほぼ同じ頻度でエラーをスローし、スタックトレースはタイマーハンドラーの1つを指します。また、onLoadCompleteを指すスタックトレースを持つタイマーがない場合もエラーをスローします...つまり、テスト関数は、エラーをスローする前に、onChildXComplete関数で1回正常に実行されています。今、私は本当に混乱しています。
public class Main extends Sprite
{
private var child1Factory:Object;
private var child1Loaded:Boolean = false;
private var child2Factory:Object;
private var child2Loaded:Boolean = false;
public function Main():void
{
Security.allowDomain("*")
if (stage) loadChildren();
else addEventListener(Event.ADDED_TO_STAGE, loadChildren);
}
private function loadChildren(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, loadChildren);
child1Loaded = false
child2Loaded = false
var child1Loader:Loader = new Loader()
child1Loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onChild1Complete)
child1Loader.load(new URLRequest("http://mywebsite.com/assets/load_test/Child1Factory.swf?" + Math.random()), new LoaderContext(false, new ApplicationDomain(ApplicationDomain.currentDomain)))
var child2Loader:Loader = new Loader()
child2Loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onChild2Complete)
child2Loader.load(new URLRequest("http://mywebsite.com/assets/load_test/Child2Factory.swf?" + Math.random()), new LoaderContext(false, new ApplicationDomain(ApplicationDomain.currentDomain)))
}
private function onChild1Complete(e:Event):void {
child1Factory = e.currentTarget.content
child1Loaded = true
var child1:MovieClip = child1Factory.getChild1()
addChild(child1)
if (child2Loaded) {
onLoadComplete()
}
}
private function onChild2Complete(e:Event):void {
child2Factory = e.currentTarget.content
child2Loaded = true
var child2:MovieClip = child2Factory.getChild2()
addChild(child2)
if (child1Loaded) {
onLoadComplete()
}
}
private function onLoadComplete():void {
var timer1:Timer = new Timer(500, 1)
timer1.addEventListener(TimerEvent.TIMER_COMPLETE, function(e:TimerEvent):void {
var child1:MovieClip = child1Factory.getChild1()
addChild(child1)
})
timer1.start()
var timer2:Timer = new Timer(1000, 1)
timer2.addEventListener(TimerEvent.TIMER_COMPLETE, function(e:TimerEvent):void {
var child2:MovieClip = child2Factory.getChild2()
addChild(child2)
loadChildren(null)
})
timer2.start()
}
}