Comunidad de diseño web y desarrollo en internet online

Cree un monstruo chupa memoria, que hago?

Citar            
MensajeEscrito el 16 Feb 2010 01:08 pm
Hola a todos, voy al grano, como lo dice el titulo he creado un monstruo que me está chupando la memoria como agua, a pesar que intento descargar todo (unload) no le llego a como hacer para que sea "garbage collector material".

Una película principal se encarga de manejar cuatro links (detallaré 2 porqué son la misma cosa), estos llevan a una película que puede tener hasta 30 links, cada link puede cargar un SWF externo. El asunto es que para que sólo se pudiera cargar un SWF a la vez (Tratando de evitar un desborde de SWF), todo lo cargo en un loader común (cargadorInfo:Loader) y para que a la vez pudiera quitarlo del display list lo incluyo en una Sprite común (displayInfo:Sprite). Entonces, para que cada categoria en mi pelicula principal se asegure que descarga tanto el material del loader como del display list al momento de darle click este ejecuta esta función:

Código ActionScript :

function borrarInfo()
{

   if(lista_alumnos_mc.displayInfo.numChildren > 0)
   {
      lista_alumnos_mc.displayInfo.removeChildAt(0);
      lista_alumnos_mc.cargadorInfo.unload();
   }
   
   if(lista_alumnos_mc.displayFondo.numChildren > 0)
   {
      lista_alumnos_mc.displayFondo.removeChildAt(0);
      lista_alumnos_mc.cargadorInfo.unload();
   }
   
   //*************************************************************
   
   if(lista_colegio_mc.displayInfo.numChildren > 0)
   {
      lista_colegio_mc.displayInfo.removeChildAt(0);
      lista_colegio_mc.cargadorInfo.unload();
   }
   
   if(lista_colegio_mc.displayFondo.numChildren > 0)
   {
      lista_colegio_mc.displayFondo.removeChildAt(0);
      lista_colegio_mc.cargadorInfo.unload();
   }
       
*/Aqui sigue el mismo cuento para los otros links, pero asi ya 
/*tienen una idea del desastre que me tengo
}


Esta función se ejecuta cada vez que uno pincha en la película principal ya sea: Clases, colegio, profesores, eventos.

El código que va en la pelicula respectiva (lista_colegio_mc, lista_alumnos_mc...), y que es el responsable de cargarme sus respectivos SWFs, es el siguiente:

Código ActionScript :

var fondo_info_mc:Sprite = new FondoAlumnosMc();
var displayInfo:Sprite = new Sprite();
var cargadorInfo:Loader = new Loader();
var displayFondo:Sprite = new Sprite();

function loadInfoContent()
{
   
   addChild(displayFondo);
   addChild(displayInfo);
   displayFondo.addChild(fondo_info_mc);
   fondo_info_mc.x = 1200;
   fondo_info_mc.y = 70;
   cargadorInfo.x = -250;
   cargadorInfo.y = -250;
   TweenMax.to (fondo_info_mc, 2, {x:250, y:70, ease:Expo.easeOut});
}


//LISTA DE ALUMNOS CLASE 01************************************************
//******************************ALUMNOS*******************************************
//***************************************************************************************

cl01_al01_btn.addEventListener(MouseEvent.CLICK, click_cl01_al01);

function click_cl01_al01(evt:MouseEvent):void
   {
      
      loadInfoContent();
      var miRequest:URLRequest = new URLRequest("cl01_calderon_vega_edwin_jesus.swf");
      cargadorInfo.load(miRequest);
      cargadorInfo.contentLoaderInfo.addEventListener(Event.COMPLETE, startListener);
      function startListener (e:Event):void
      {
         displayInfo.addChild(cargadorInfo);
      }
   }
//*****************************************************************************

cl01_al02_btn.addEventListener(MouseEvent.CLICK, click_cl01_al02);

function click_cl01_al02(evt:MouseEvent):void
   {
      loadInfoContent();
      var miRequest:URLRequest = new URLRequest("cl01_leiva_monge_melania.swf");
      cargadorInfo.load(miRequest);
      cargadorInfo.contentLoaderInfo.addEventListener(Event.COMPLETE, startListener);
      function startListener (e:Event):void
      {
         displayInfo.addChild(cargadorInfo);
      }
   }
//*****************************************************************************


Esto se repite en todas las listas con todos los links, etc. Aqui puse dos links nada más para que puedan tener una idea de como está el código.

El asunto está en que no puedo dejar el cargadorInfo = null porqué me dispara problemas ya que es totalemente común y el problema mayor es que como dije, esto es un pozo sin fondo!!!.

Alguien me podría echar la mano para ver como puedo descargar de la memoria los SWF que cargo al momento de darle click a cualquiera de los links llamados "Colegio, clases..." en mi Movie principal.

Agradezco cualquier ayuda, como pueden ver en el código soy bastante nuevo en esto y la verdad es que no sé como para donde salir corriendo al ver como me DRAGA la memoria el bichito este que me inventé :lol:.

Saludos y gracias por su tiempo.

Por djburner

19 de clabLevel



 

firefox
Citar            
MensajeEscrito el 16 Feb 2010 04:22 pm
El metodo unload remueve de escena el loader asi que no es necesario que juegues con removeChild, recuerdo que cuando intento tener algo aprecido a lo tuyo me tiraba errores porq a veces mandaba descargar el loader cuando no tenia nada cargado...yo nada mas validaba if(loader.parent!=null){loader.unload();}.
Ese aumento de memoria se va dar claro porq acabas de cargar un nuevo swf, al momento de descargarlo debes asegurarte de no dejar ningun listener en dicho swf y mas complicado aun si ese swf tiene codigo debes eliminar todos los listeners internos,timers y cualquier cosa que pueda seguir ejecutandose, yo comunmente pongo en cada swf un metodo Kill() que mando llamar antes de descargarlo y este metodo Kill() se encarga de detener cualquier cosa en mi swf,hay una nueva funcion(no tan nueva ya) para el player 10 que es unloadAndStop() investiga un poco de ella(en la misma documentacion) es mas simple descargar cosas con esa funcion.

Puede ser que si se descarguen tus swf's pero el garbage collector aun no corre,hay una funcion System.gc(); esta funcion solo funciona en modo debug osea que al exportar el archivo de flash para probarlo esta funcion va forzar una pasada del GC al llamarla con esto puedes comprobar si el garbage se lleva esa memoria extra (OJO esta funcion es innutil fuera de flash si abres el swf normalemnte no hara nada, no bases tu optimizacion en ella).

Cuando estas cargando muchas cosas con un mismo loader debes estar conciente que el llamar un nuevo metodo load() no detiene la carga anterior si estas cargando un swf y el usuario pica un boton (les encanta picar a lo loco ;)) que carga otro swf antes de cargarse el anterior tu comenzaras la carga del nuevo mientras el segundo sigue alli cargandose para esto utiliza el metodo close() del loader.

Saludos!! Espero te sirva de algo.

Por Angel Roberto

Claber

248 de clabLevel



 

firefox
Citar            
MensajeEscrito el 16 Feb 2010 04:40 pm
Gracias AngelRoberto por tu tiempo, por el momento sigo con el Flash 9 (CS3) por lo tanto aun no tengo el unloadAndStop(), que ya me hace pensar en moverme de inmediato, pero ya el proyecto lo tengo avanzado.

Sin duda voy a reducir mi código con tu mejor código de validar el if(loader.parent!=null){loader.unload();}., muy efectiva, mil gracias.

Pero lo del Kill() esto SÍ que me interesa porqué creo que es mi luz: Efectivamente los swf que se cargan están llenos de timers para crear movimientos de galerias, cargan videos, texto, etc, yo creia (noobie) que al descargar el SWF del movie principal era un todo, osea un adios al SWF y listo, pero veo que no es asi, me podrias explicar un poquito más a fondo esta solución tuya de la función kill(); me imagino que ella la incluyes en el SWF que va a ser cargado en el loader. Osea lo incluyes en los swf que se cargan en la movie principal ¿cierto?

De antemano quedo muy agradecido amigo..

Por djburner

19 de clabLevel



 

firefox
Citar            
MensajeEscrito el 16 Feb 2010 06:54 pm
Amigo he intentado por el momento seguir tratando de eliminar cosas, ahora le cambié los listeners para que sean weak reference"

cl01_al01_btn.addEventListener(MouseEvent.CLICK, click_cl01_al01, false, 0, true);

Pero nada, sigue chupando memoria como deshidratado (lo sé xq forcé al GC llamando el método: flash.system.System.gc(); y la memoria igual de llena) . Voy a seguir dándole coco, hasta ahora creo que llevo: Loaders descargados, display list limpia, listeners weak, pero si me serviría mucho que me contaras un poquito más sobre ese Kill() que mencionaste.Gracias y saludos.

Por djburner

19 de clabLevel



 

firefox
Citar            
MensajeEscrito el 16 Feb 2010 07:10 pm
El Kill() es exactamente como lo i maginaste es una funcion que va en cada swf,tmb te recomiendo que no pongas codigo en linea de tiempo porq en algun aldo lei que con codigo en linea de tiempo no se descargaba bien el swf (que alguien me corrija si me equivoco) como quiera es mejor tener todo en un "document class" lo que yo implemento es una funcion publica Kill de modo que la llamo antes del unload:

Código ActionScript :

//Un casting a movieclip
MovieClip(loader.content).Kill();


Pero que hay en esa funcion Kill() eso ya depende del swf dices que tienes timers animaciones blablabla...
para timer lo que hago es remover cada listener del timer, si el timer esta corriendo lo detengo y lo nulifico

Nota:Ignora mi sintaxis todo lo escribo de memoria

Código ActionScript :

//Remueves cada timer yo pongo los dos que siempre uso pero remueve cada timer que agregues
timer.removeEventLsitener(TimerEvent.TIMER,funcion);
timer.removeEventLsitener(TimerEvent.TIMER_COMPLETE,funcion);

if(timer.running){timer.stop();}
timer=null;


Para las animaciones si son con un enterFrame remueves el listener y listo,en caso de usar algo como TweenLite (que te lo recomiendo muchisimo) tiene un metodo KillTweens..o algo asi no lo recuerdo del todo pero este metodo detiene los tweens aplicados a un objeto.

En caso de usar el Tween de adobe la cosa se complica mas...en primer lugar los tweens de adobe se traban (se los lleva el garbage) para evitar esto y tener un control de los tweens yo los agrego a un arreglo global de tweens e implemento una funcion que detiene cada tween y una que los elimina.

Es comun que agreguemos listeners a botones y cosas varias en la pantalla yo siempre agrego todos esos listeners en una sola funcion y asi mismo tengo una funcion que remueve todos...asi nada en escena se queda con un listener,simplemente recuerda...cada addlistener debe tener un removelistener.

Hay muchas formas de optimizacion no usar Number cuando solo se necesita un int no crear variables dentro de ciclos for cosas asi que son mas de mejores practicas al programar puedes buscar mucho en google sobre como optimizar tu codigo.

Saludos!!

Por Angel Roberto

Claber

248 de clabLevel



 

firefox
Citar            
MensajeEscrito el 16 Feb 2010 11:14 pm
Un mons.....llama a los cazafantasmas .jajaa broma

Por xcom

Claber

530 de clabLevel



 

firefox
Citar            
MensajeEscrito el 17 Feb 2010 08:13 am
AngelRoberto, muchas gracias. sin duda voy a implementar tus consejos al código y le informaré como avanza el asunto para que otros usuarios no cometan el MISMO error de novato. Estoy haciendo reserch. Saludos y gracias por toda la ayuda. Este sitio es un gran salvavidas.

hahahaha, man la verdad que si llegan los cazafantasmas se tiran por la ventana al ver como se devora el ram este bicho!!!! El hombre de marshmallow ni los mandados le hace!!!. :lol:

Por djburner

19 de clabLevel



 

firefox
Citar            
MensajeEscrito el 17 Feb 2010 03:40 pm
Sale estare aqui al pendiente :)...si cristalab tmb me a sacado de buenos apuros.

Por Angel Roberto

Claber

248 de clabLevel



 

firefox
Citar            
MensajeEscrito el 17 Feb 2010 10:17 pm
recuerda no llames al gb mas que una ayuda relentiza tus aplicaciones , ya esta programado eso automaticamente en flash

Por xcom

Claber

530 de clabLevel



 

firefox
Citar            
MensajeEscrito el 19 Feb 2010 03:56 am
He implementado bastantes tips al código, ahora me queda más claro que para descargar un SWF completamente hay que eliminar todas las referencias. Pero sucede algo curioso. Este es el código de entrada de un intro (SWF creado en After). La primera pasada que se dispara automaticamente descarga el SWF perfectamente (RESPIRÉ). Pero la segunda que carga el SWF dese un boton, y teninendo en cuanta quees la misma misma función (con diferente nombre), el SWF se queda pegado en la memoria, le di una hora al GC y nada. El código si lo notan es exactamente el mismo, pero en una si funciona y en la otra no, ¿Cual sería entonces la referencia en el segundo caso (que se dispara con un botón) para que de alguna manera el GC no elimine el SWF de memoria? Contando que no tiene loader, URLReference, listener, ni timers.

Código ActionScript :


var miIntro:Loader = new Loader();
var miIntroRequest:URLRequest = new URLRequest("After/Presentacion/presentacion_final.swf");
miIntro.load(miIntroRequest);
addChild(miIntro);
miIntro.x = 0; 
miIntro.y = 0;

var myTimerBack:Timer = new Timer(14000); 
myTimerBack.start();
myTimerBack.addEventListener(TimerEvent.TIMER, backUp);
function backUp(evt:TimerEvent):void
{
   addChild(background_mc);
   addChild(logo_college_mc);
   addChild(pestana_interna_left_mc);
   addChild(pestana_left_mc);
   addChild(pestana_right_mc);
   myTimerBack.stop();
   myTimerBack = null;
   miIntro.unload();
   miIntro = null;
   miIntroRequest = null;
}

control_general_mc.load_intro_btn.addEventListener(MouseEvent.CLICK, loadIntro2);
function loadIntro2(evt:MouseEvent):void
{
   var miIntro2:Loader = new Loader();
   var miIntroRequest2:URLRequest = new URLRequest("After/Presentacion/presentacion_final.swf");
   miIntro2.load(miIntroRequest2);
   addChild(miIntro2);
   miIntro2.x = 0; 
   miIntro2.y = 0;
   var myTimerBack2:Timer = new Timer(14000); 
   myTimerBack2.start();
   myTimerBack2.addEventListener(TimerEvent.TIMER, backUp2);
   function backUp2(evt:TimerEvent):void
   {
      addChild(background_mc);
      addChild(logo_college_mc);
      addChild(pestana_interna_left_mc);
      addChild(pestana_left_mc);
      addChild(pestana_right_mc);
      myTimerBack2.stop();
      myTimerBack2 = null;
      miIntro2.unload();
      miIntro2 = null;
      miIntroRequest2 = null;
   
   }
   control_general_mc.load_intro_btn.removeEventListener(MouseEvent.CLICK, loadIntro2);
}


Gracias por la ayuda, esto sé que me está ayudando mucho en mi trabajo y espero que ayude a otros en este tema que me doy cuenta es tan crítico.

Por djburner

19 de clabLevel



 

firefox
Citar            
MensajeEscrito el 19 Feb 2010 05:31 am
perdon por entrometerme pero la carga y descarga de un swf esta en que un swf a "cargar" se le agregan los listeneres ADDED_TO_STAGE y REMOVED_FROM_STAGE , cuando es escuchado el added tu swf se puede decir que inicializa su aplicacion : variables, listeners etc , al removed haces destroy de objetos , listeners etc y en la clase main solo igualas a null la propiedad content del Loader que es la que contiene el swf cargado , asi el Loader lo puedes reutilizar al cargar otro contenido.


Jonathan

Por maneuver

243 de clabLevel



Genero:Masculino  

Mexico City

firefox
Citar            
MensajeEscrito el 20 Feb 2010 12:47 pm
Hola amigo, implemente lo que me mencionaste, si entendí bien, la mejor manera es utilizando ADD_TO_STAGE y REMOVED_FROM_STAGE para una mejor ejecucion y eliminacion de SWF. Implementé tu código pero no me da ningún error, el problema es que nada aparece en la pantalla. Mi problema es que aun no he podido entender como trabajar fluidamente con "Document Class" desde el as. Entonces todo lo voy programando en el primer frame de mi Main movie.

El código me quedo así, pero como te digo, no da error pero no pasa nada, ¿estoy bien? o me equivoqué, si es así te agradecería si me puedes poner algún ejemplo de como ejecutar tu solución con este código y así talvez pueda comprender mejor. de todas formas quedo muy agradecido por tu tiempo y ayuda.

Código ActionScript :

control_general_mc.load_intro_btn.addEventListener(MouseEvent.CLICK, loadIntro2, false, 0, true);
function loadIntro2(evt:MouseEvent):void
{
   var miIntro:Loader = new Loader();
   var miIntroRequest:URLRequest = new URLRequest("After/Presentacion/presentacion_final.swf");
   miIntro.load(miIntroRequest);
   miIntro.addEventListener(Event.ADDED_TO_STAGE, addedIntro);
   function addedIntro(evt:Event):void
   {
      addChild(miIntro);
      miIntro.x = 0; 
      miIntro.y = 0;

      var myTimerBack:Timer = new Timer(14000); 
      myTimerBack.start();
      myTimerBack.addEventListener(TimerEvent.TIMER, backUp);
      function backUp(evt:TimerEvent):void
      {
         addChild(background_mc);
         addChild(logo_college_mc);
         addChild(pestana_interna_left_mc);
         addChild(pestana_left_mc);
         addChild(pestana_right_mc);
         miIntro.addEventListener(Event.REMOVED_FROM_STAGE, removedIntro);
         function removedIntro(evt:Event):void
         {   
            myTimerBack.stop();
            myTimerBack = null;
            miIntro.unload();
            miIntro = null;
            miIntroRequest = null;
            control_general_mc.load_intro_btn.removeEventListener(MouseEvent.CLICK, loadIntro2);
         }
      }
   }
}

Por djburner

19 de clabLevel



 

firefox
Citar            
MensajeEscrito el 20 Feb 2010 04:24 pm
esto es algo muy preguntado y ya lo he respondido pero no hayo el post , asi que haver aqui va un ejemplo , tengo un fla *Main* con 2 botones con nombre de instancia "mLoadSWF" , mCloseSWF . Un segundo fla *Externo* con un movieclip que es un circluo con nombre de intancia "mBall" este swf sera el que cargaremos , ok entonces el codigo

SWF Principal *Main* 1 Frame :

Código ActionScript :

//contenedor vacio para el swf
var _container:Sprite = new Sprite();
_container.x = 20;  _container.y = 80;
addChild(_container);

//objeto cargador
var _loader:Loader = new Loader();
//listeners
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);

function completeHandler(e:Event):void
{
   //un swf es o se comporta como un MovieClip asi que hare un variable que haga referencia
   //al content del loader que es el tiene el swf cargado
   var swfLoaded:MovieClip = e.target.content as MovieClip;
   //lo agrego al contenedor
   _container.addChild(swfLoaded);
}

//listeners event click de los Movieclips *botones*
mLoadSWF.addEventListener(MouseEvent.CLICK, clickLoadHandler);
mCloseSWF.addEventListener(MouseEvent.CLICK,clickCloseHandler);

//event click MovieClip mLoadSWF
function clickLoadHandler(e:MouseEvent):void
{
   //cargamos el swf 
   _loader.load(new URLRequest("assets/swfA.swf"));
   //le agrego el listener del evento que se dispara cuando sea descargado el swf
   _loader.contentLoaderInfo.addEventListener(Event.UNLOAD, unloadHandler);
}

//event click MovieClip mCloseSWF
function clickCloseHandler(e:MouseEvent):void
{
   //si en el contenedor hay un 1 hijo es por que tiene un swf carga asi que lo removeremos
   if(_container.numChildren > 0) {
      //removes el hijo del contenedor
      _container.removeChildAt(0);
      //descargamos el loader y como se descargo se disparar el evento unload
      _loader.unload();
      
   }else {
      trace("contains no children");
   }
}

//event unload del objeto _loader
function unloadHandler(e:Event):void
{
   _loader.contentLoaderInfo.removeEventListener(Event.UNLOAD,unloadHandler);
   //hacemos una prueba
   trace("_loader.content =" ,_loader.content);
}


SWF A *Externo* 1 Frame :

Código ActionScript :

//init Listeners
addEventListener(Event.ADDED_TO_STAGE, addedHandler);
addEventListener(Event.REMOVED_FROM_STAGE, removedHandler);

//variables
var _speed:Number;
var _angle:Number;
var _centerX:Number;
var _centerY:Number;
var _radiusX:Number;
var _radiusY:Number;

//cuando es agregado el stage esta listo
function addedHandler(e:Event):void
{
   //removemos el Listener para tener light el swf
   removeEventListener(Event.ADDED_TO_STAGE, addedHandler);
   //llamamos a la funcion que inicia la aplicacion
   initAnimation();
}

function removedHandler(e:Event):void
{
   //removemos el Listener
   removeEventListener(Event.REMOVED_FROM_STAGE, removedHandler);
   //llamamos a la funcion que se encarga de mandar al fuck los objetos y listeners
   destroy();
}

function initAnimation():void
{
   //les damos un valor a la variables ya declaradas
   _speed = 0.1;
   _angle = 0;
   _centerX = 150;
   _centerY = 90;
   _radiusX = 150;
   _radiusY = 50;
   
   //agrego un listener enter_frame para hacer una simple anamiacion
   mBall.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
   
}

function destroy():void
{
   //removemos e igualamos a null
   mBall.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
   mBall = null;
   trace(" todo se fue al fuck !! .. mBall = " , mBall);
}

function enterFrameHandler(e:Event):void
{
   var ball:MovieClip = e.target as MovieClip;
   ball.x = _centerX + Math.cos(_angle) * _radiusX;
   ball.y = _centerY + Math.sin(_angle) * _radiusY;
   _angle += _speed;
}


eso es todo el codigo esta comentado creo que si debes poder entenderlo y adaptarlo a tus necesidades

Jonathan

Por maneuver

243 de clabLevel



Genero:Masculino  

Mexico City

firefox
Citar            
MensajeEscrito el 21 Feb 2010 03:30 am
Amigo muchas gracias por tu tiempo e invaluable colaboración, apenas estoy revisando el mensaje pero antes de entrarle no quería dejar pasar ni un minuto para decirte cuanto aprecio tu ayuda (al igual que a todos en el post). Voy a empezar a digerirlo para implementarlo y postearé los resultados. Sin duda es lo que estoy buscando por la razón de enviar al $%&* los benditos SWFs.

Saludos.

Por djburner

19 de clabLevel



 

firefox
Citar            
MensajeEscrito el 21 Feb 2010 10:48 am
Ok, he avanzado mucho, el SWF que voy a cargar no me da ningún problema, lo probé y reprobé y el código excelente. Pero sucede esto en el Movie Principal que al darle al bóton designado para descargar el SWF no se va del todo, ni desaparece. Creo haber entendido muy bien el código, por eso me extraña este comportamiento, segui todos los pasos pero aun así da ese problema. Sólo tengo que aclarar que como van a ser como 150 links de carga, el código del main movie (Que me diste) lo estoy escribiendo en el primer frame de un MovieClip (Como van varias categorias me imagino que no es ningún problema, pero por si aquello porque desde ahi es desde donde quiero cargar todas las cosas. (Antes claro -como me dijiste- lo probé originalmente en el primer frame del Movie Principal pero me pasó lo mismo, el archivo lo carga excelente, pero cuando le doy click al boton de descargar no pasa nada.

Código ActionScript :


var displayInfo:Sprite = new Sprite();
var cargadorInfo:Loader = new Loader();
cargadorInfo.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
addChild(displayInfo);

function completeHandler(evt:Event):void
{ 
        var swf:MovieClip = evt.target.content as MovieClip;
   displayInfo.addChild(swf);
}

cargar_btn.addEventListener(MouseEvent.CLICK, clickLoadHandler);
function clickLoadHandler(evt:MouseEvent):void
{
   
   cargadorInfo.load(new URLRequest("mySwfTest.swf"));
   cargadorInfo.contentLoaderInfo.addEventListener(Event.UNLOAD, unLoadHandler);
}

descargar_btn.addEventListener(MouseEvent.CLICK, clickCloseHandler);
function clickCloseHandler(evt:MouseEvent):void
{
   if (cargadorInfo.numChildren > 0)
   {
      cargadorInfo.removeChildAt(0);
      cargadorInfo.unload();
   }
}
   
function unLoadHandler(e:Event):void
{
   cargadorInfo.contentLoaderInfo.removeEventListener(Event.UNLOAD,unLoadHandler);
   trace("Loader Content", cargadorInfo.content);
}



Creo que todo está correcto, pero como te cuento, el SWF no se va, y si le doy de nuevo al botón cargar_btn me sale un

Código ActionScript :

Loader Content null
ArgumentError: Error #2025: El objeto DisplayObject proporcionado debe ser un elemento secundario del llamador.
   at flash.display::Loader/_load()
   at flash.display::Loader/load()
   at ListaAlumnosMc/clickLoadHandler()


Aquí dejo el código del SWF que va a ser cargado, la verdad es que lo puedes brincar porqué es una copia prácticanmente con pequeñas adaptaciones.

Código ActionScript :


addEventListener(Event.ADDED_TO_STAGE, addedHandler);
addEventListener(Event.REMOVED_FROM_STAGE, removedHandler);

var logo_mc:MovieClip = new LogoMc();

function addedHandler(evt:Event):void
{
   removeEventListener(Event.ADDED_TO_STAGE, addedHandler);
   initAnimation();
}

function removedHandler(evt:Event):void
{
   removeEventListener(Event.REMOVED_FROM_STAGE, removedHandler);
   destroy();
}


function initAnimation():void
{

   addChild(logo_mc);
   logo_mc.x = 100;
   logo_mc.y = 200;
   logo_mc.addEventListener(Event.ENTER_FRAME, logoWalk);
   
}
   
function logoWalk(evt:Event):void
{
   logo_mc.x += 10;
}
   
function destroy():void
{
   logo_mc.removeEventListener(Event.ENTER_FRAME, logoWalk);
   logo_mc = null;
}


Yo creo que ya entendi muy clarito como funciona el ADDED y REMOVE_FROM, para que el SWF ejecute funciones apartir de que si el SWF esta incluido o descargado del Stage y si está descargado dispara el destroy que elimina todos los listener, enter frames, timers, etc. Ya solo me queda ese problema con el botón de descarga. Al menos estoy más cerca, jeje. :lol:

Por djburner

19 de clabLevel



 

firefox
Citar            
MensajeEscrito el 22 Feb 2010 06:57 pm
Estas agregando el "content" del cargador en un sprite y para descargarlo lo que haces es checar si el cargador tiene "hijos" pero en realidad no lo tiene porq reparentaste el swf cargado.

Por Angel Roberto

Claber

248 de clabLevel



 

firefox
Citar            
MensajeEscrito el 26 Feb 2010 01:00 pm
Vaya que lucha, que frustrante por Dios, estoy que tiro la toalla, monté el ejemplo más Básico del mundo y no me funciona, yo sé que me han dado mucha ayuda pero no le llego, ya cambié a CS4 a ver si podia utilizar el unloadAndStop pero el método es sumamente agresivo y puede causar resultados no deseados.

AngelRoberto ya lo quite del displayInfo para no reparentarlo, aun asi con este código el botón descargar no lo descarga.

¿Por donde podría estár mal el código para no descargarlo porqué yo no lo veo? El código del "mySwfTest.swf" sigue siendo el mismo que puse anteriormente, lo que hice fue sólo desparentarlo del sprite, tratando de llevar este ejemplo a la mínima expresión pero ni así.

Código ActionScript :


var cargadorInfo:Loader = new Loader();
cargadorInfo.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);

function completeHandler(evt:Event):void
{ 
   var swf:MovieClip = evt.target.content as MovieClip;
   addChild(swf);
}

cargar_btn.addEventListener(MouseEvent.CLICK, clickLoadHandler);
function clickLoadHandler(evt:MouseEvent):void
{
   
   cargadorInfo.load(new URLRequest("mySwfTest.swf"));
   cargadorInfo.contentLoaderInfo.addEventListener(Event.UNLOAD, unLoadHandler);
}


//event unload del objeto _loader
descargar_btn.addEventListener(MouseEvent.CLICK, clickCloseHandler);
function clickCloseHandler(evt:MouseEvent):void
{
   if (cargadorInfo.numChildren > 0)
   {
      cargadorInfo.removeChildAt(0);
      cargadorInfo.unload();
   }
}
   
function unLoadHandler(e:Event):void
{
   cargadorInfo.contentLoaderInfo.removeEventListener(Event.UNLOAD,unLoadHandler);
   trace("Loader Content", cargadorInfo.content);
}



Lo que voy a decir es pura y verde frustración pero respeto el trabajo impresionante del equipo de desarrollo de Adobe, pero como puede ser posible que algo tan utilizado como cargar swfs se complique pero RETANTO eliminarlos con un unload y ADIOS para siempre, prácticamente es escribir Doble código para detener listeners, timers, enter frames, referencias, variables etc , y si se escapó una variable al carajo todo, ufff.

En fin, necesitaba sacarlo de mi sistema, volviendo al caso de esta forma no me da ningún error, pero como dije no se desaparece el SWF del stage. Alguien ve el problema que ya yo sólo veo chinos con sombrilla. Gracias a todos por toda su ayuda y soporte.

Por djburner

19 de clabLevel



 

firefox
Citar            
MensajeEscrito el 26 Feb 2010 06:12 pm
Lo sigues reparentando,entiendo tu frustracion pero poco a poco se te va hacer el pan de cada dia.

Checale la documentacion y el metodo un load funciona cuando el laoder a descargar esta en escena, el padre de tu swf cargado es el loader que lo carga y tu lo reparentas aqui:

Código ActionScript :

function completeHandler(evt:Event):void 
{  
   var swf:MovieClip = evt.target.content as MovieClip; 
   addChild(swf); 
} 


Cambia eso por:

Código ActionScript :

function completeHandler(evt:Event):void 
{  
   addChild(cargadorInfo); 
} 


Un obejto no puede tener mas de un padre asi que al momento de hacer:

Código ActionScript :

var swf:MovieClip=evt.target.content as MovieClip;
addChild(swf);

cargador info deja de ser el padre de swf de modo que cuando haces esto:

Código ActionScript :

function clickCloseHandler(evt:MouseEvent):void 
{ 
   if (cargadorInfo.numChildren > 0) 
   { 
      cargadorInfo.removeChildAt(0); 
      cargadorInfo.unload(); 
   } 
} 

Cargadorinfo no tiene hijos y no descarga nada,cambia el codigo como te dije y en la parte de la descarga yo siempre uso:

Código ActionScript :

function clickCloseHandler(evt:MouseEvent):void 
{ 
      try{
      cargadorInfo.unload(); 
    }catch(e:*){}
} 



Si la descarga no se pudiera hacer y generara un error el try'catch lo cacha y la aplicacion sigue como si nada y si removiste listeners,timers y detuviste cualquier proceso se descargara

Por Angel Roberto

Claber

248 de clabLevel



 

firefox
Citar            
MensajeEscrito el 26 Feb 2010 07:09 pm
Hola Angel gracias por tu paciencia y palabras de apoyo, espero no romperte las pelotas, de hecho agregar el addChild(cargadorInfo) fue justamente donde comencé y funciona de maravilla, sólo que el problema que me da es que a pesar de que lo descargaba perfectamente de la pantalla, no lo descarga de la memoria.

Así quedó el código tratando de hacerlo lo más simple del mundo.


Código ActionScript :


var cargadorInfo:Loader = new Loader();
cargadorInfo.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler, false, 0, true);

function completeHandler(evt:Event):void
{ 
   addChild(cargadorInfo);
}

cargar_btn.addEventListener(MouseEvent.CLICK, clickLoadHandler, false, 0, true);
function clickLoadHandler(evt:MouseEvent):void
{
   cargadorInfo.load(new URLRequest("mySwfTest.swf"));
}

descargar_btn.addEventListener(MouseEvent.CLICK, clickCloseHandler, false, 0, true);
function clickCloseHandler(evt:MouseEvent):void
{
    try
    { 
        cargadorInfo.unload();  
    }catch(e:*){} 
}


//*********

Ahora lo que le implementé es la forma de la función que me dices con el try & catch, antes lo tenia con un

Código ActionScript :


if(cargadorInfo.content)
{
cargadorInfo.unload();
}



Y además tambien le agregué los weak references a los listeners (los probé weak y normales, el resutlado es el mismo). Ambas formas me parecen que tienen que hacer la tarea, pero el bendito swf sigue pegado en la memoria.

Es que en serio, estoy tratando de entender las cosas para no molestar tanto con esto, pero como vez copiando prácticamente el código y con un swf que tiene un solito objeto y un solito listener y que supuestamente los destruyo, el swf no se va. ¿Cuál puede ser la referencia que quede por ahi para que no se vaya del todo?. Si este ejemplo que estoy haciendo tiene 4 lineas o menos de código y naa de naa.

Por djburner

19 de clabLevel



 

firefox
Citar            
MensajeEscrito el 26 Feb 2010 10:42 pm
Debes tener conciencia que el darle unload y remover todas las referencias deja al swf listo para que el garbage se lo lleve esto quiere decir que tienes que esperar a que el garbage corra y lo descargue de verdad, como ya te habia comentado a modo de saber si se lo lleva el garbage o no,puedes usar la funcion System.gc() pero recuerda que solo sirve para debug en la vida real no tienes forma de forzar el garbage.

No te quiebres tanto la cabeza esperando liberar la memoria en su totalidad es del saber de todos que flash aun no lo hace a la perfeccion (si no es asi,que alguien me diga como lograr liberarla toda XD).

Saludos!!

Por Angel Roberto

Claber

248 de clabLevel



 

firefox
Citar            
MensajeEscrito el 26 Feb 2010 10:53 pm
Debes tener conciencia que el darle unload y remover todas las referencias deja al swf listo para que el garbage se lo lleve esto quiere decir que tienes que esperar a que el garbage corra y lo descargue de verdad, como ya te habia comentado a modo de saber si se lo lleva el garbage o no,puedes usar la funcion System.gc() pero recuerda que solo sirve para debug en la vida real no tienes forma de forzar el garbage.

No te quiebres tanto la cabeza esperando liberar la memoria en su totalidad es del saber de todos que flash aun no lo hace a la perfeccion (si no es asi,que alguien me diga como lograr liberarla toda XD).

Saludos!!

Por Angel Roberto

Claber

248 de clabLevel



 

firefox
Citar            
MensajeEscrito el 26 Feb 2010 10:54 pm
Ups mensaje duplicado.....culpa del internet :P

Por Angel Roberto

Claber

248 de clabLevel



 

firefox
Citar            
MensajeEscrito el 27 Feb 2010 04:16 am
AngelRoberto en realidad no sabes lo agradecido que estoy con toda la ayuda de tu parte y de la que he encontrado en el sitio, he aprendido mucho (demaciado) de todos. Por hoy voy a sentar la cabeza, descansar un poco, voy a recurrir a más documentación y sin duda trataré de implementar algunas otras soluciones a mi problema para que no sea la frustración la que tome la perspectiva.

Mañana actualizaré algunos datos pero sin duda por hoy voy a descansar y dejarlos descansar también de darle a este tambor.
Que pases un muy buen fin de semana.
Saludos y paz desde Costa Rica a todos.

Por djburner

19 de clabLevel



 

firefox

 

Cristalab BabyBlue v4 + V4 © 2011 Cristalab
Powered by ClabEngines v4, HTML5, love and ponies.