Pregunta

Feliz Pre-Halloween a todos :)

Mi problema hoy es un error de DisplayObject que obtengo cuando elimino un objeto secundario. Tengo un código que iniciará (addChild) un contenedor de video y controles de video, así como también agregará un botón de cierre. Ahora el botón de cierre funciona bien y todo , quitando el video y los controles y estoy puedo elegir otro video nuevamente, pero cuando haces clic en cerrar por segunda vez, aparece este error:

ArgumentError: Error # 2025: El DisplayObject suministrado debe ser hijo de la persona que llama. en flash.display :: DisplayObjectContainer / removeChild ()

Así que reduje el problema a donde elimino el videoContainer (que contiene el objeto de video)

Mi código para reproducir los videos:

public function videoSwitch(videoName):void
{
    nv.closeOut();
    nv.resetNav = false;

    if (!videoPlaying)
    {
        vc = new VideoClass(videoName, videoHolder);
        vc.addEventListener("KillMovie", removePlayer);
        container.addChild(videoContainer);
        container.addChild(vc);
        //container.addChildAt(videoContainer, 1);
        //container.addChildAt(vc, 2);
        videoPlaying = true;
        closeVideo();
    }

    else if (videoPlaying)
    {
        vc.clearSource();
        container.removeChild(videoContainer);
        container.removeChild(vc);

        vc = new VideoClass(videoName, videoHolder);
        vc.addEventListener("KillMovie", removePlayer);
        container.addChild(videoContainer);
        container.addChild(vc);
        //container.addChildAt(videoContainer, 1);
        //container.addChildAt(vc, 2);
        closeVideo();
    }
        trace("videoPlaying = "+videoPlaying+"\r");
}

El código de cierre del reproductor de video: Puedes ver en mis comentarios otro código que probé, pero aún obtengo el error.

function closeVideo():void 
{
    closeBtn.visible = true;
    closeBtn.x = 770;
    closeBtn.y = 20;
    closeBtn.buttonMode = true;
    container.addChild(closeBtn);
    closeBtn.addEventListener(MouseEvent.MOUSE_UP, closeButtonClicked);

    function closeButtonClicked(event:MouseEvent):void 
    {
        vc.clearSource();
        container.removeChild(videoContainer);
        //container.removeChildAt(videoContainer, 1);
        container.removeChild(vc);
        videoPlaying = false;
        closeBtn.visible = false;
    }
}

Ahora mi película funciona bien, pero me preocupa que este error ocurra en segundo plano (y que aparece en mi ventana de salida) eventualmente causará un problema más donde :(

Gracias de antemano por cualquier mirada en este! :)


ACTUALIZACIÓN: ¡ARREGLADO! El problema fue que eliminé el oyente kill VC, pero olvidé eliminar el estúpido oyente Mouse_Event de Close Button :(

function addCloseButton():void 
{
    container.addChild(closeBtn);
    closeBtn.addEventListener(MouseEvent.MOUSE_UP, closeButtonClicked);

    function closeButtonClicked(event:MouseEvent):void 
    {
        videoPlaying=false;
        vc.clearSource();
        removeContainerChildren(); // <- thx Joel!
        closeBtn.removeEventListener(MouseEvent.MOUSE_UP, closeButtonClicked);
        //^ Forgot this line - thx Jotham!
        container.removeChild(closeBtn);
    }
}

No sé si este gráfico ayuda pero: texto alternativo ??

¿Fue útil?

Solución

¿Alguna vez eliminaste al oyente? Bien podría estar haciendo que se dispare varias veces.

Otros consejos

aquí hay un enfoque para evitar el error:

    public function videoSwitch(videoName):void
    {
        nv.closeOut();
        nv.resetNav = false;

        if (videoPlaying)
        {
            vc.clearSource();
            removeContainerChildren()
        }

        addContainerChildren();
        closeVideo();
    }

    protected function removeContainerChildren():void
    {
        if(container.contains(videoContainer))
            container.removeChild(videoContainer);
        if(container.contains(vc))
        {
            container.removeChild(vc)   
            vc.removeEventListener("KillMovie", removePlayer)
        }
    }

    protected function addContainerChildren():void
    {
        videoPlaying = true;
        vc = new VideoClass(videoName, videoHolder);
        vc.addEventListener("KillMovie", removePlayer, false, 0, true); 
        container.addChild(videoContainer);
        container.addChild(vc);

        trace("videoPlaying = "+videoPlaying+"\r");
    }

Prueba esto:

 container.removeChild(container.videoContainer);
 container.removeChild(container.vc);

Tengo la sensación de que es otro código lo que causa el problema real. Este error tendría sentido si la variable videuPlaying se cambiara en otro lugar, de modo que eliminara algo que aún no existía. Quizás compruebe que no está cambiando esta variable en otro lugar.

Esta es otra forma súper hacky de hacer esto, generalmente no se recomienda, pero definitivamente asegurará que el videoContainer / vc se elimine de la DisplayList en la que se encuentre.

private function removeFromStack(target:DisplayObject):void
{
    if (target.parent)
        target.parent.removeChild(target);
}

private function removeVideo():void
{
    removeFromStack(vc);
    removeFromStack(videoContainer);
    vc = videoContainer = null;
}

Solo para volver a iterar, esta no es la forma preferida, pero funcionará sin errores. Si comienza a obtener un " no puede acceder a la referencia de objeto nulo " error, entonces, como han sugerido otras personas, los DisplayObject ' s en cuestión aún mantienen los oyentes de eventos u otras dependencias.

Espero que esto ayude

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top