在删除的swf中杀死setTimeOut

时间:2015-04-28 11:50:24

标签: actionscript-3 flash

//以下函数用于删除加载的swf

private function LoaderKaldir()
		{
			System.pauseForGCIfCollectionImminent(0.50);	
			try 
			{
				for(var sts:int=0;sts<=20;sts++)
			    clearTimeout(sts);
				removeChild(calistirilacakSwf);
				calistirilacakSwf.unloadAndStop(true);
				System.gc();
				calistirilacakSwf = null;
				SoundMixer.stopAll();
				
/*				calistirilacakSwf.content.addEventListener(Event.UNLOAD, function() { 
					SoundMixer.stopAll();
					trace("silindi")
				} );*/
			}
			catch (e:*) { trace("loader kaldır hata verdi" + e) }
			try
			{
				efektserbesilkhali = target.effectSerbest; 
				target.effectSerbest = false;
			}catch(e:*){}
		
//following is belong to loaded swf
package 
{
	import flash.display.Loader;
	import flash.display.MovieClip;
	import flash.events.*;
	import flash.geom.Rectangle;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.net.URLRequest;
	import flash.utils.Timer;
	import fl.transitions.Tween;
	import fl.transitions.TweenEvent;
	import fl.transitions.easing.*;
	import com.greensock.*;
	import com.greensock.easing.*;
	import flash.utils.setTimeout;

	public class a1_3 extends MovieClip
	{
		private var yolum:String;
		public var dogruCevap:String = "birinci";
		private var imageyolu:String;
		private var twn:Tween;
		private var twn1:Tween;
		private var twn2:Tween;
		private var twn3:Tween;
		var twn4:Tween;

		public function a1_3()
		{
			yollari();
		}

		private function yollari()
		{
			/*trace(this.root.loaderInfo.url);*/


			var yol:String = this.root.loaderInfo.loaderURL;
			imageyolu = imageyolu = "/17/1/1/";
			if (yol.indexOf("bilisselbecerilermodulu") != -1)
			{
				var sonrakiler:String = yol.split("bilisselbecerilermodulu")[1];

				var sayilari:int = sonrakiler.split("/").length - 1;
				yolum = "";
				for (var i = 0; i < sayilari; i++)
				{
					yolum +=  "../";
				}
			}
			else
			{
				yolum = "../../../../";
			}

			addEventListener(Event.ENTER_FRAME,baslat);
		}

		private function baslat(evt:Event)
		{
			removeEventListener(Event.ENTER_FRAME,baslat);
			zeminleriYukle(yolum+"images/17/1/zemin1.png",stage.stageWidth/2-660, 250,yolum+"images/17/1/zemin.png",stage.stageWidth/2+40,250);
		}

		private function zeminleriYukle(yol:String,xkor:Number,ykor:Number,yol1:String,xkor1:Number,ykor1:Number)
		{
			var zmnyl:URLRequest = new URLRequest(yol);
			var zmnldr:Loader = new Loader();
			zmnldr.load(zmnyl);
			addChild(zmnldr);
			zmnldr.x = xkor;
			zmnldr.y = ykor;
			zmnldr.contentLoaderInfo.addEventListener(Event.COMPLETE, zeminOzellestir);
			var zmnyl1:URLRequest = new URLRequest(yol1);
			var zmnldr1:Loader = new Loader();
			zmnldr1.load(zmnyl1);
			addChild(zmnldr1);
			zmnldr1.x = xkor1;
			zmnldr1.y = ykor1;
			zmnldr1.contentLoaderInfo.addEventListener(Event.COMPLETE, zeminOzellestir1);
			var karmasik:int = Math.floor(Math.random() * (1 + (1) - 0)) + 0;
			if (karmasik == 0)
			{
				zmnldr1.name = "zemin1";
				zmnldr.name = "zemin";
			}
			else
			{
				zmnldr1.name = "zemin";
				zmnldr.name = "zemin1";
			}
		}

		private function zeminOzellestir(evt:Event)
		{
			evt.target.content.smoothing = true;
			evt.target.content.width = evt.target.content.width * 0.9;
			evt.target.content.height = evt.target.content.height * 0.9;
		}

		private function zeminOzellestir1(evt:Event)
		{
			evt.target.content.smoothing = true;
			evt.target.content.width = evt.target.content.width * 0.9;
			evt.target.content.height = evt.target.content.height * 0.9;
			nesneleriGetir(yolum + "images"+imageyolu+"1.png", yolum + "images"+imageyolu+"2.png");
		}

		private function nesneleriGetir(yol:String,yol1:String)
		{
			var nsnyl:URLRequest = new URLRequest(yol);
			var nsnldr:Loader = new Loader();
			nsnldr.load(nsnyl);

			nsnldr.name = "birinci";
			nsnldr.contentLoaderInfo.addEventListener(Event.COMPLETE, nesneOzellestir);
			//birinci görsel yani soldaki görsel doğru ise burası deger("1") olacak sağdaki doğru ise deger("0") olacak, nsnldr.mouseEnabled = false; kodu aynı kalacak;
			nsnldr.addEventListener(MouseEvent.CLICK, function() {
			var img:Object=getChildByName("birinci"); 
			 for (var i:uint = 0; i < numChildren; i++){ 
			 if (getChildAt(i).name != img.name) 
			 {TweenMax.to(getChildAt(i), .6, { blurFilter: { blurX:12, blurY:12 }} );}}  
			 twn = new Tween(img, "width",Elastic.easeOut ,img.width,img.width * 2, 2, true);  
			 twn1 = new Tween(img, "height", Elastic.easeOut ,img.height,img.height * 2, 2, true); 
			 nsnldr.mouseEnabled = false;
			 deger("1");
			
			});
			addChild(nsnldr);

			var nsnyl1:URLRequest = new URLRequest(yol1);
			var nsnldr1:Loader = new Loader();
			nsnldr1.load(nsnyl1);
			//ikinci görsel yani sağdaki görsel doğru ise burası deger("1") olacak soldaki doğru ise deger("0") olacak, nsnldr.mouseEnabled = false; kodu aynı kalacak;
			nsnldr1.addEventListener(MouseEvent.CLICK, function() {
			deger("0");
			nsnldr1.mouseEnabled = false;
			});
			nsnldr1.name = "ikinci";
			nsnldr1.contentLoaderInfo.addEventListener(Event.COMPLETE, nesneOzellestir);
			addChild(nsnldr1);

		}

		private function setRegPoint(obj:DisplayObjectContainer, newX:Number, newY:Number):void
		{
			var bounds:Rectangle = obj.getBounds(obj.parent);
			var currentRegX:Number = obj.x - bounds.left;
			var currentRegY:Number = obj.y - bounds.top;
			var xOffset:Number = newX - currentRegX;
			var yOffset:Number = newY - currentRegY;
			obj.x +=  xOffset;
			obj.y +=  yOffset;
			for (var i:int = 0; i < obj.numChildren; i++)
			{
				obj.getChildAt(i).x -=  xOffset;
				obj.getChildAt(i).y -=  yOffset;
			}
		}



		private function nesneOzellestir(evt:Event)
		{
			removeEventListener(Event.COMPLETE,nesneOzellestir);
			//setRegPoint(evt.target.content, evt.target.content.width , evt.target.content.height);
			if (evt.currentTarget.content.parent.name == "birinci")
			{
				evt.target.content.smoothing = true;
				evt.target.content.width = evt.target.content.width * 0.6;
				evt.target.content.height = evt.target.content.height * 0.6;
				evt.target.content.x = getChildByName("zemin").x + getChildByName("zemin").width / 2 - evt.target.content.width / 2.4;
				evt.target.content.y = getChildByName("zemin").y + getChildByName("zemin").height / 2 - evt.target.content.height / 2.4;
				setRegPoint(evt.currentTarget.content.parent,evt.currentTarget.content.parent.width/2,evt.currentTarget.content.parent.height/2);
			}
			else if (evt.currentTarget.content.parent.name == "ikinci")
			{
				evt.target.content.smoothing = true;
				evt.target.content.width = evt.target.content.width * 0.6;
				evt.target.content.height = evt.target.content.height * 0.6;
				evt.target.content.x = getChildByName("zemin1").x + getChildByName("zemin1").width / 2 - evt.target.content.width / 2.4;
				evt.target.content.y = getChildByName("zemin1").y + getChildByName("zemin1").height / 2 - evt.target.content.height / 2.4;
				setRegPoint(evt.currentTarget.content.parent,evt.currentTarget.content.parent.width/2,evt.currentTarget.content.parent.height/2);

			}
			ilkSesiGetir();
		}
		private function ilkSesiGetir()
		{
			var ikincisesyolu:URLRequest = new URLRequest(yolum+"sound/17/1274(1).mp3");
			var ses:Sound = new Sound(ikincisesyolu);
			ses.play();
			setTimeout(bkl,1000);
			function bkl()
			{
				twn1 = new Tween(getChildByName("ikinci"),"x",Strong.easeOut,getChildByName("ikinci").x,getChildByName("birinci").x,2,true);
				twn3 = new Tween(getChildByName("birinci"),"x",Strong.easeOut,getChildByName("birinci").x,getChildByName("ikinci").x,2,true);
				twn2 = new Tween(getChildByName("ikinci"),"y",Elastic.easeOut,getChildByName("ikinci").y - 40,stage.stageHeight / 2,3,true);
				twn2 = new Tween(getChildByName("birinci"),"y",Elastic.easeOut,getChildByName("birinci").y + 40,stage.stageHeight / 2,3,true);
			}
		}


		function deger(degerlendirme)
		{
			var p:MovieClip = this.parent.parent as MovieClip;
			p.sonuc(degerlendirme);
			trace(degerlendirme);
		}


	}
}

我将一个swf文件导入主swf,当我点击下一个按钮将其删除并加载一个新的swf文件时,当一个新的swf加载到主swf中时,还有从前一个swf播放的声音。 SoundMixer.stopAll();无法解决问题。 System.gc();也不起作用。主要原因是我使用setTimeOut播放声音。即使我删除swf,settimeout也会在估计的时间后工作。 任何建议都会得到满足。

2 个答案:

答案 0 :(得分:0)

查看手册:http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/utils/package.html#setTimeout()

据说setTimeout会返回uint - Unique numeric identifier for the timed process. Use this identifier to cancel the process, by calling the clearTimeout() method.

因此,如果您想清除此超时,简单的clearTimeout(sts);将无效。您需要执行以下操作:

var timeoutId = setTimeout(bkl,1000);
clearTimeout(timeoutId);

不确定这是否可以在整个swf文件中使用,但是你总是可以在加载的swf中插入任何公共方法,你可以从父进程调用,这样就可以在那里进行清除。

答案 1 :(得分:0)

根据Loader/unloadAndStop documentation,如果您使用Timers代替setTimeout,则会停止。

例如,可以像这样执行1秒超时:

var timer:Timer = new Timer(1000, 1);
timer.addEventListener(TimerEvent.TIMER_COMPLETE, timerComplete);
timer.start();

function timerComplete(e:TimerEvent):void {
    // do stuff
}

执行此操作需要额外的代码,但您可以将其包装在全局util函数中,就像setTimeout一样:

package {
    public function doTimeout(delay:uint, callback:Function):Timer {
        var timer:Timer = new Timer(delay, 1);
        timer.addEventListener(TimerEvent.TIMER_COMPLETE, function(e:TimerEvent):void {
            timer.removeEventListener(TimerEvent.TIMER_COMPLETE, arguments.callee);
            callback();
        });
        timer.start();
        return timer;
    }
}

用法:

doTimeout(1000, callback);

注意:您可能需要将返回的Timer存储在某处,否则可能会收集垃圾。我不是百分百肯定。

另一种选择是使用某种可以轻松清除所有超时的全局管理器:

public class Timeout {
    private static var timeouts:Vector.<int> = new <int>[];
    public static function add(delay:uint, callback:Function):int {
        var timeout:int = setTimeout(delay, callback);
        timeouts.push(timeout);
        return timeout;
    }
    public static function clearAll():void {
        for each(var id:int in timeouts){
            clearTimeout(id);
        }
    }
}

不要直接使用setTimeout,而是使用Timeout.add(),当您卸载SWF时,请致电Timeout.clearAll()清除所有待处理的超时。

修改 您目前正在使用此解决方法:

for(var sts:int = 0; sts <= 20; sts++)
    clearTimeout(sts);

这将只清除设置的前20个超时。这非常脆弱。稍微好一点的解决方法是循环遍历所有超时,这可以通过检查当前超时ID来确定:

var i:uint = setTimeout(function(){}, 0);
while(i--)
    clearTimeout(i);

这仍然有些脆弱:我找不到任何保证超时id实际上是有序的文档,尽管这似乎是行为。此外,大概一旦达到uint的最大值,它就会循环回到0.但这是一个巨大的数字。

此外,如果当前超时id是一个非常大的数字,循环可能会导致挂起。你可以通过仅清除最后1000次超时来避免这种情况。总而言之,这是一个相当脆弱的解决方案。