Вопрос

Всем счастливого предХэллоуина :)

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

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

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

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

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

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

Заранее спасибо за внимание к этому!:)


ОБНОВЛЯТЬ: ЗАФИКСИРОВАННЫЙ! Проблема заключалась в том, что я удалил прослушиватель kill VC, но забыл удалить дурацкий прослушиватель Close Button 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

Это было полезно?

Решение

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

Другие советы

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

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

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

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

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

Это еще один очень хакерский способ сделать это, обычно не рекомендуемый, но он определенно гарантирует, что 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'это под вопросом.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top