AS3 повторное использование переменной - PullRequest
2 голосов
/ 11 декабря 2011

Мне трудно понять, что я ожидаю, чтобы быть основным принципом в управлении памятью. Надеюсь, кто-то может предложить объяснение, которое поможет мне лучше понять.

Я объявил одну переменную класса slideShow.

var slideShow:SlideShow;

function addSlideShow(e:MouseEvent):void {

    slideShow = new SlideShow();    
    addChild(slideShow);

}

function clearSlideshow (e:MouseEvent):void {

    removeChild(slideShow);

}

Если я дважды вызываю функцию addSlideShow, два экземпляра класса SlideShow будут созданы и добавлены на сцену.

Если я вызываю clearSlideshow дважды, со сцены удаляется только один экземпляр. Второй вызов создает ошибку.

Я думаю, что каждый раз, когда я вызываю addSlideShow, переменная slideShow будет перезаписываться новым экземпляром SlideShow, поэтому будет создан только один экземпляр. Это явно не тот случай.

Имея это в виду, является ли следующий правильный способ обработки вещей, где я удаляю и обнуляю переменную slideShow перед созданием нового экземпляра?

var slideShow:SlideShow;

function addSlideShow(e:MouseEvent):void {

try {
        removeChild(slideShow);
        slideShow = null;
    } catch (e:Error) {
        trace(e);
    }

    slideShow = new SlideShow();    
    addChild(slideShow);

}


function clearSlideshow (e:MouseEvent):void {

    try {
        removeChild(slideShow);
        slideShow = null;
    } catch (e:Error) {
        trace(e);
    }   
}

Спасибо за любую помощь, которую вы можете предложить.

Ответы [ 4 ]

4 голосов
/ 11 декабря 2011

Переменная не получает перезаписанной .Существует разница между объектами, которые вы создаете с помощью new, и ссылкой slideShow, которая указывает на первый объект слайд-шоу, а затем указывает на второй объект.Здесь происходит то, что у вас больше нет прямой ссылки на первый объект, поэтому вы не можете удалить его, как пытаетесь это сделать.Конечно, где-то еще есть ссылка, так как объектом являются дети сцены.Таким образом, они не будут собирать мусор.

Распространенным решением является использование массива и push всех его экземпляров, поэтому у вас есть ссылка для их удаления позже.

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

function addSlideShow(e:MouseEvent):void {
    addChild(new SlideShow()); // don't need any explicit reference now.
}

function clearSlideshow (e:MouseEvent):void {
    if(e.target is SlideShow){
        removeChild(e.target);
    }
}
1 голос
/ 11 декабря 2011
  • При втором вызове addSlideShow вы просто теряете свою ссылку к первому объекту SlideShow. Ничто не разрушается, ничто не удаляется, это должен сделать сборщик мусора.

  • Однако, если этот более ранний объект SlideShow был добавлен с использованием addChild, он все еще на него ссылается родительский объект, в который он был добавлен, поэтому сборщик мусора не удалит его.

  • Если вам нужно отслеживать два экземпляра, вам нужно создать два отдельных эталонные объекты. Так что лучшая идея для нескольких объектов обычно Массив. Заполните массив и удалите из массива.

  • Поскольку родитель хранит ссылку на всех своих детей, которых вы можете получить и без массива. Просто переберите .children или идентифицировать их методами getChildByName.

1 голос
/ 11 декабря 2011

Второй вызов clearSlideshow () завершается неудачно, поскольку у вас нет указателя на элемент, который вы хотите удалить:

  1. Первый вызов addSlideShow (): вы создаете слайд-шоу "A". На него ссылается слайдшоу var.

  2. Второй вызов addSlideShow (): вы создаете слайд-шоу "B". На него ссылается слайдшоу вар. У вас больше нет ссылки на "A", так как переменная slideShow была перезаписана.

  3. Первый вызов clearSlideshow (): вы удаляете дочернего объекта, на которого указывает слайд-шоу, то есть «B».

  4. Второй вызов clearSlideshow (): Вы просите снова очистить дочерний объект, на который указывает slideShow, т.е. «B», но этот дочерний элемент отсутствует в вашем списке дочерних элементов, поскольку он уже удален.

Если вы хотите иметь возможность ссылаться на слайд-шоу «A» и «B», вы должны иметь что-то, что позволяет вам ссылаться на любой из них (возможно, массив слайд-шоу).

0 голосов
/ 11 декабря 2011

В вашем первом примере первый добавленный SlideShow не удаляется GC, потому что сцена все еще содержит ссылку на него.Второй вызов removeChild() завершается неудачно, потому что объект, который вы даете в качестве аргумента, уже удален со сцены.

Ваша вторая попытка должна делать то, что вы хотите, но вам не нужно устанавливать slideShow до null.Так как вы все равно назначаете новый объект для slideShow, ссылок на первый экземпляр больше не будет (если какой-то другой код, который вы не показывали, ссылается на него), и он будет удален GC.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...