![]() |
Удаление объектов из иерархии отображения
Представим себе такую последовательность действий:
1. Создаем объект (сохранив на него ссылку) 2. Отслеживаем наступления некоторого события (не связанного с помещением или удалением объекта в/из иерархии отображения) 3. Добавляем объект в иерархию отображения 4. Удаляем объект из иерархии отображения 5. Удаляем ссылку на объект, созданную на первом шаге По сути flash удалит объект, когда ему это понадобится, если ссылок на объект не осталось. Вопрос такой: понятно, что события, обозначенные в шаге 2 не наступят. Но удалится ли объект? Т.е. будет ли считаться, что мы стерли ВСЕ ссылки на объект? И еще момент: представим, что в наш объект были размещены другие объекты (ссылки на которые не сохранились), за которыми так же следили (addEventListener). После проделанных шагов 4 и 5, будут ли под-объекты считаться пригодными для выбрасывания? Надеюсь, достаточно четко объяснил суть вопроса. Заранее спасибо! |
Мне не совсем понятно, почему события в шаге 2 не наступят, но Вам виднее. Объект не удалится, потому что был шаг 1.
По моменту. addChild оставляет ссылку на ребенка у родителя в списке детей. Т. o. объекты не будут считаться пригодными для выбрасывания до тех пор, пока не произойдет removeChild. |
Цитата:
Цитата:
|
флеш не настолько умный. Все ссылки лучше занулять(включая удаляемых детей). И обязательно удалять всех слушателей.
|
Цитата:
как обойти всех детей - я знаю. тогда вопрос: как зная объект, найти всех назначенных слушателей (т.е. пару тип и значение слушателя)? |
Цитата:
|
Цитата:
т.е. необходимо следить за каждым подписанием и сохранять его - тоже выход, конечно. просто не универсальный. спасибо. и можно на "ты". |
Цитата:
|
Цитата:
ведь так можно рассматривать объект, чтобы удалить всех его детей, добавленных методом addChild() не отслеживая этого. |
В правильно начатом проекте проблемы отписывания от событий в принципе не возникнет.
|
Цитата:
я просто хотел понять, есть ли необходимость удалять всех детей и слушателей, если я хочу удалить родителя. |
Удаление детей должен произвести сам удаляемый объект.
|
Цитата:
|
в общем случае, я делаю метод destroy, который запускает destroy у всех детей, а потом зануляет свои ссылки и убивает слушателей. Уж свои-то листенеры объект должен знать.
|
Цитата:
|
зануляет ссылки внутри себя. Убить ссылку на него - задача уже его родителя.
Непонимаю в чем проблемы, любой программист, который учился программированию на cpp или даже pascal имеет понимание о том, как освободить память. |
Цитата:
|
Цитата:
меня просто удивила формулировка вашего ответа - потому и уточнил. Цитата:
|
Присоединяюсь к __etc.
Но сделаю замечание: занулять все ссылки, удалять всех детей и делать кучу других лишних действий (в общем случае) - это гемор чистой воды. Нужно занулять (и снимать слушатели) только то, что действительно необходимо ;) Деструкторы в классах тогда будут занимать больше чем сами классы )) Зануления и удаления могут немного ускорить процесс "mark" у GC (garbage collector), не более. Важно четко и правильно понимать как флэш работает с памятью. Тогда проблем с "нужно/не нужно" не будет. P.S. Какие бы профи не были в команде разрабов, без Flex Profiler порой не обойтись ;) P.P.P.P.P.S. ну и те кто пишут свои проги в Flash IDE, не прогеры... )))) гы |
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
В общем-то проверьте профайлером: Код AS3:
Код AS3:
Насчет удаления слушателей надо понимать лишь, что такое слушатель, и как оно работает. А работает оно как-то так: http://www.javaworld.com/javaworld/j...04-events.html child.addEventListener(event, parentFunc) в массив _listeners ребенка кладет ссылку на parentFunc. А т. к. это дело изолировано в ребенке, то ничего казалось бы не помешает флэшу удалить спокойно child из памяти, если на него не осталось ссылок. Но из-за особенности флэшовских событий (bubbling) в родителе тоже возможно сохраняются ссылки на ребенка - мое предположение. Поэтому: Цитата:
Кстати, может кто знает, нет ли где-нибудь статьи, в которой описана модель событий флэша на очень детальном уровне? Т. е. фактически как написать класс EventDispatcher идентичный флэшовому. |
s8000_1, мдя ... ни какой ГЦ не имеет отношения ни к какой событийной модели, и уж тем болие к её баблингу. Ваш пример не связывает больше 3х кусочков различных частей приложения, поэтому поймать тут, что-то типа утечки будет сложно... но если вдруг получится так, что Вам придётся передать хотя бы на одного ребёнка Test ссылку, вся ваша конструкция целиком повиснет в памяти после удаления, а не только тот несчастный ребёнок. и так как Денис разрабатывает приложение состоящие не из 2х классов, что-то мне подсказывает, что он не раз встречался с ситуацией, что случайно не убитый слушатель тянет за собой, целую ветку своих родителей, которые в свою очередь тянут за собой своих детей.
|
интересное обсуждение.
должен заметить, что в Муке ничего про удаление слушателей как и детей нет. Точнее там просто не затрагивается тема удаления под детей в освобождении памяти. |
я пишу игрушки. На as3. Там постоянно создаются объекты, удаляются, эти объекты взаимодействуют с другими объектами, держат в себе ссылки на них. И постоянно ловлю утечки памяти. В больших MMO на флеш - и timeZero, и в Dofus, я тоже вижу, как с каждым часом клиент сжирает все больше и больше оперативы. Могу сказать уверенно, что GC во флеше очень неторопливый и совершенно тупой.
Так что в моих проектах зануление не лишнее. И не занимает больше места, чем сами классы, это уж точно. А когда я на заказ делаю какую-нибудь галерею - я даже не заморачиваюсь. |
Цитата:
|
Цитата:
По поводу ссылок на ребенка Test - это логично, что вся конструкция повиснет в памяти, т. к. в самом этом ребенке есть ссылка на родителя. Но если делать объекты изолированными (взаимодействие с внешним миром через события и публичные функции самого объекта), то все будет удаляться нормально. Все равно ведь удаление детей и слушателей - перестраховка на случай что-то упустить. iNils, лишние слушатели - это те, которые ловят событие не в target-фазе. А если Вы не добавляете объект на сцену, эти слушатели не создадутся. |
s8000_1, как у Вас всё утопично ... в жизни бы так :)
|
BlooDHounD, но Вы разве не согласны, что ручное удаление - перестраховка или "правило хорошего тона", а не необходимость? И что EventDispatcher можно переписать самому и понять, кто где может создавать ссылки на слушателей и объекты, испускающие события.
Я сам-то лично удаляю слушателей и детей (их по возможности) на случай "вдруг забуду обнулить где-то внешнюю ссылку". |
это необходимость. в команде разработчиков нельзя гарантировать, что второй разработчик соблюдёт все нюансы Вашей безалаберности.
|
столько разлагольствования, чтобы в итоге выяснить, что в большом проекте все занулять необходимо
|
Цитата:
легко проверить тестовым путем, что надо чистить абсолютно все. в идеале каждый класс должен иметь некоторый метод destroy(). и etc прав - в правильно начатом проекте такой проблемы не возникнет, если каждый класс будет иметь свой метод очистки и вся иерархия будет построена так, что при удалении экземпляра класса родителя, удаляются все его детишки. |
| Часовой пояс GMT +4, время: 13:52. |
Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.