Получение ошибки при использовании метода removeChild - PullRequest
2 голосов
/ 30 октября 2009

С праздником всех до Хэллоуина :)

Моя проблема сегодня - ошибка DisplayObject, которую я получаю при удалении дочернего объекта. У меня есть код, который будет запускать (addChild) контейнер видео и элементы управления видео, а также добавить кнопку закрытия. Теперь кнопка закрытия работает нормально и все , удаляя видео и элементы управления, и я снова могу выбрать другое видео, но когда вы нажимаете кнопку закрыть второй раз, я получаю эту ошибку:

ArgumentError: Ошибка # 2025: предоставленный объект DisplayObject должен быть дочерним по отношению к вызывающей стороне. на flash.display :: DisplayObjectContainer / removeChild ()

Итак, я сузил проблему до того места, где я удаляю videoContainer (который содержит видеообъект)

Мой код для воспроизведения видео:

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");
}

Код закрытого видеоплеера: Вы можете увидеть в моих комментариях другой код, который я пробовал, но все равно получаю ошибку.

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;
    }
}

Теперь мой фильм работает нормально, но я беспокоюсь, что эта ошибка, происходящая в фоновом режиме (и появляющаяся в моем окне вывода), в конечном итоге вызовет проблему, где: (

Заранее спасибо за любые глаза на это! :)


UPDATE: ИСПРАВЛЕНО! Проблема заключалась в том, что я удалил прослушиватель kill VC, но забыл удалить тупой слушатель кнопки закрытия Mouse_Event: (

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);
    }
}

Не знаю, помогает ли этот рисунок, но: alt text

Ответы [ 5 ]

2 голосов
/ 30 октября 2009

Вот один из способов избежать ошибки:

    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");
    }
1 голос
/ 31 октября 2009

Это еще один хакерский способ сделать это, обычно не рекомендуется, но он определенно гарантирует, что videoContainer / vc будет удален из того, что DisplayList включено.

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

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

Просто повторюсь, это не предпочтительный способ, но он будет работать без ошибок. Если вы начинаете получать сообщение об ошибке «невозможно получить доступ к нулевой объектной ссылке», то, как и предполагали предыдущие люди, прослушиватели событий или некоторые другие зависимости все еще удерживаются соответствующими DisplayObject' s.

Надеюсь, это поможет

1 голос
/ 31 октября 2009

Вы когда-нибудь удаляли слушателя? Вы могли бы хорошо разжечь его несколько раз.

1 голос
/ 31 октября 2009

У меня такое ощущение, что это какой-то другой фрагмент кода, вызывающий настоящую проблему. Эта ошибка имеет смысл, если переменная videuPlaying была изменена где-то еще, так что вы удаляете что-то, что еще не существует. Возможно, проверьте, что вы не меняете эту переменную где-то еще.

1 голос
/ 30 октября 2009

Попробуйте это:

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