Удаление родителя в AS3: Освобождает ли это память, используемую всеми дочерними элементами?

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

Я дам еще немного объяснений на случай, если я не выражаю то, что хочу:

addChild(movie1);
movie1.addChild(movie2);
movie1.addChild(movie3);

Используя этот код:

removeChild(movie1);

Удаляет ли он movie2 и movie3 из памяти или они все еще хранятся, просто отключенные?


person Dan Hanly    schedule 17.09.2010    source источник


Ответы (3)


Что ж, пока ничего не удаляется из памяти, это действительно зависит от того, как ссылаются на movie1. Предположим, что позже в приложении, которое вы захотите снова добавить movie1, вы должны обнаружить, что movie1 не только все еще здесь, но также содержит movie2 и movie3.

var movie1:MovieClip;

whatever();
anotherMethod();

function whatever():void
{
    movie1 = new MovieClip();
    var movie2:MovieClip = new MovieClip();
    var movie3:MovieClip = new MovieClip();
    movie1.addChild(movie2);
    movie1.addChild(movie3);
    addChild(movie1);

    whateverElse();
}

function whateverElse():void
{ 
    //here, nothing is garbage collected, movie1 exists outside
    //the scope of this function
    removeChild(movie1);

    //now you can
    tryThis();

    //but if you do this you're effectively killing movie2 & movie3 , since
    //they're not referenced anywhere else.
    removeChild(movie1);
    movie1 = null;

    //this is going to throw an error , movie1's gone!
    tryThis();
}

function tryThis():void
{
    //yes ,it's still here with all its content
    addChild(movie1);
}

function anotherMethod():void
{
    var movieN:MovieClip = new MovieClip();
    var movie2:MovieClip = new MovieClip();
    var movie3:MovieClip = new MovieClip();
    movieN.addChild(movie2);
    movieN.addChild(movie3);

    // do all you need to do... 
    // then
    removeChild( movieN);
    getOut();
}

function getOut():void
{
   //life goes on without movieN, movie2 & movie3
   //waiting to be garbage collected
}
person PatrickS    schedule 17.09.2010
comment
Итак, ответ таков, что да, если я хочу полностью удалить его из памяти, я должен удалить все дочерние элементы, а ЗАТЕМ его родительский элемент, чтобы приложение было плотным. - person Dan Hanly; 18.09.2010
comment
если на movie2 и movie3 не ссылается какой-либо другой объект, достаточно удалить movie1. посмотрите на код! в anotherMethod () я удаляю только movieN, а в getOut () movieN больше не упоминается, поэтому три фрагмента ролика будут собраны в мусор - person PatrickS; 18.09.2010

Если на movie2 и movie3 больше не ссылается другой объект, они должны быть удалены сборщиком мусора. То же самое касается movie1.

Из Создание визуальных компонентов Flex в ActionScript:

Чтобы программно удалить элемент управления, вы можете использовать методы removeChild () или removeChildAt (). Вы также можете использовать метод removeAllChildren () для удаления всех дочерних элементов управления из контейнера. Вызов этих методов фактически не удаляет объекты. Если у вас нет других ссылок на дочерний элемент, Flash Player в будущем включит его в сборку мусора. Но если вы сохранили ссылку на этот дочерний элемент на каком-либо объекте, этот дочерний элемент не удаляется из памяти.

person splash    schedule 17.09.2010
comment
Я согласен и настоятельно рекомендую загрузить и просмотреть презентацию, которую вы можете найти здесь: в блогах. adobe.com/aharui/2007/03/. Это немного устарело, но очень хорошо объясняет механизм сборки мусора. - person David; 17.09.2010

Конечно, он удаляет все 3.

У ребенка в фильме 1 есть двое детей, в фильме2 + 3. Если он умрет из-за болезни Инстанса, дети, возможно, тоже умрут.

Может я ошибаюсь, но вы также можете попробовать:

trace(movie2);
person Community    schedule 17.09.2010
comment
Их не обязательно удалять, потому что на них всегда может ссылаться другой объект. - person splash; 17.09.2010
comment
Я не думаю, что выполнение trace(movie2); имеет значение, поскольку вы не знаете, когда сборщик мусора запустит и удалит movie2. - person David; 17.09.2010