Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Система удаления ненужных объектов и слушателей (http://www.flasher.ru/forum/showthread.php?t=204878)

Tails 13.11.2013 18:54

Цитата:

... ведь слушатели детей всё равно надо удалять отдельно, или нет?
Отписываться надо только от внешних диспетчеров. Глобальный таймер в игре, подписки на stage, внешние диспетчеры и т.п.

Запомните пожалуйста, "слушатель" который вы создаёте, находится в том объекте, над которым вы вызвали addEventListener. Если этот объект находится в области родительского контейнера, нет необходимости отписываться.

Цитата:

и каждому объекту пропишу метод destroy() с удалением слушателей и обнулением ссылок - на GC больше надежды нет, вручную вернее будет.
Правильно этот метод называется: dispose(). Обязательно попробуйте.
И "вручную" вам никак не удалить объект. Вы не имеете прямого доступа к памяти. Полностью удаляет - только gc.

Akopalipsis 13.11.2013 19:09

Цитата:

В этом варианте, контейнер не удалился бы. Подумайте почему.
Открыл Мука, главу о статических свойствах, всё что там написано, это - статические переменные создаются для самого класса. То есть, если обычные переменные обьявленные и инициализированные на уровне класса, в экземплярах будут иметь свои значения, то статические во всех экземплярах сохранят своё значение. Если я правильно понял, то если я создам экземпляр класс А содержащий статическое свойство массив и положе в него обьект, то при создании второго экземпляра класса А, в этом массиве будет находится обьект помещённый первым экземпляром.
Но вот как это выглядит в коде я не понимаю. И я не понимаю, почему если я в класс Container передам ссылку на статическое свойство, обявленное в классе Main, Container не удалится.. Подскажите пожалуйста :)

gloomyBrain 13.11.2013 19:41

Цитата:

То есть, если обычные переменные обьявленные и инициализированные на уровне класса, в экземплярах будут иметь свои значения, то статические во всех экземплярах сохранят своё значение.
Есть класс и у него есть свойство. Есть экземпляр и у него тоже есть свои свойства.
Статические свойства принадлежат классу, а не "во всех экземплярах сохранят своё значение".

Цитата:

И я не понимаю, почему если я в класс Container передам ссылку на статическое свойство, обявленное в классе Main, Container не удалится..
Удалится. Не удалится, если наоборот.


Цитата:

Запомните пожалуйста, "слушатель" который вы создаёте, находится в том объекте, над которым вы вызвали addEventListener
Вообще я бы выразился иначе. Рассмотрим конструкцию:
Код AS3:

dispatcher.addEventListener(Event.COMPLETE, someFunc);

Фактически, мы говорим вот что:
"Диспатчер, вот тебе ссылка на someFunc, вызови ее когда посчитаешь, что произошел Event.COMPLETE".

Таким образом, тот, кто отсылает событие (dispatcher), имеет ссылку на того, кто его получает (someFunc и объект, которому она принадлежит). Именно этим и руководствуется GC при просмотре ссылок для удаления объектов.

Tails 13.11.2013 19:44

Akopalipsis,
Сами классы всегда доступны. Их Статические свойства и методы то-же. Любой объект, добавленный в статическое свойство класса (или список в статическом свойстве) - никогда не удалится, потому-что до него "можно достучаться".

gloomyBrain 13.11.2013 19:53

Цитата:

Сами классы всегда доступны. Их Статические свойства и методы то-же. Любой объект, добавленный в статическое свойство класса (или список в статическом свойстве) - никогда не удалится, потому-что до него "можно достучаться".
Вообще "можно достучаться" только если сам класс доступен. А классы вполне себе можно выгружать из ApplicationDomain, если это необходимо. И если класс выгружен, то очевидно что и статическое свойство канет в лету вместе с ним.

Akopalipsis 13.11.2013 20:13

Спасибо Вам за ответы!
Цитата:

Удалится. Не удалится, если наоборот.
Естественно, вместе в вопросом, я начал профайлере пробовать удаления и что самое интересное,
что либо он не удаляется и в случаи, когда переменная _object и в Main и в Container обьявлена обычной,
либо удаляется, даже если она обьявлена статической. Так как профайлер показывает, что в обоих случаях
Count и Memory становятся ноль 0, а Maximum всегда 1..

a7s1h1 13.11.2013 20:55

Цитата:

Сообщение от Tails (Сообщение 1152252)
Отписываться надо только от внешних диспетчеров. Глобальный таймер в игре, подписки на stage, внешние диспетчеры и т.п.

Запомните пожалуйста, "слушатель" который вы создаёте, находится в том объекте, над которым вы вызвали addEventListener. Если этот объект находится в области родительского контейнера, нет необходимости отписываться.

Получается, что при удалении родителя из детей достаточно удалить лишь ссылки на другие объекты, а всё остальное автоматически сгинет вместе с родителем? Как-то подозрительно просто...
И ещё, пройдя путь от восторга до презрения по отношению к GC, я до сих пор не могу понять: следует ли вообще где-то в коде писать System.gc, если в релизе GC всё равно будет запускаться, когда вздумается ему? Или я опять всё напутал?

Akopalipsis 13.11.2013 21:04

Вам нужно вот что понять ( могу ошибаться сам, но если я не прав, поправьте ), вот Вы создали экземпляр класса ПервыйУровень. Ссылка на него должна быть только в одном месте, в месте его инициализации.
В этом экземпляре Вы создаете всё что нужно, но только так, чтобы на созданное ссылки были только у экземпляра ПервыйУровень. И вот когда Вы удалите экземпляр ПервыйУровень, то всё что в нем есть, будет доступно для GC, так ссылок на содержимое ПервыйУровень больше не у кого нет.

dimarik 14.11.2013 00:20

Цитата:

Сообщение от a7s1h1 (Сообщение 1152261)
Получается, что при удалении родителя из детей достаточно удалить лишь ссылки на другие объекты

С точностью до наоборот. Не из детей ссылки на другие объекты, а ссылки на детей из этих объектов. Объект жив, когда на него есть ссылка. Если есть хоть одна ссылка на дите, то оно будет жить. И пишите код так, чтобы общение детей с внешним миром происходило через его родитель. Ну или добавляйте детские хендлеры с мягкими ссылками, например, в источник данных в data-driven компонентах. Тогда вообще себе голову не нужно ничем забивать.

И не нужно дергать GC самостоятельно. Оно для отладки только сделано. Если хочется повлиять на работу GC, то можно применить pauseForGCIfCollectionImminent (Flash Player 11, AIR 3). Рассказывают как оно работает.

a7s1h1 14.11.2013 11:43

Цитата:

Сообщение от dimarik (Сообщение 1152290)
С точностью до наоборот. Не из детей ссылки на другие объекты, а ссылки на детей из этих объектов. Объект жив, когда на него есть ссылка.

Начинаю догонять... Но как же мне при удалении объекта узнать, ссылается на него кто-то или нет? Кроме того, такой подход подразумевает, что придётся перед обращением к любому объекту проверять, существует ли он.

Цитата:

Сообщение от dimarik (Сообщение 1152290)
Ну или добавляйте детские хендлеры с мягкими ссылками, например, в источник данных в data-driven компонентах.

Ой, это мне, наверное, пока рано - после слова "например" не понял ничего:wacko:. Пошёл учить матчасть

Цитата:

Сообщение от dimarik (Сообщение 1152290)
И не нужно дергать GC самостоятельно. Оно для отладки только сделано.

Спасибо, теперь я окончательно решил отказаться от GC и чистить всё сам.


Часовой пояс GMT +4, время: 08:54.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.