Форум 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=155554)

Srednas 06.05.2011 08:50

Удаление всех слушателей
 
Здравствуйте.

Вопрос:
Удалятся ли слушатели детей, если не делать removeEventListener, а просто удалить родительский объект? После удаления родительского объекта, создается точно такой же но уже с другим количеством детей.

И еще:
Можно ли как-то удалить все слушатели, включая, слушатели на детях?

goodguy 06.05.2011 10:19

Цитата:

Удалятся ли слушатели детей, если не делать removeEventListener, а просто удалить родительский объект?
Нет
Цитата:

Можно ли как-то удалить все слушатели, включая, слушатели на детях?
Нет

Можно вешать слушатели не на детей, а на сам родительский котейнер.
Либо для каждого объекта добавлять слушатель Event.REMOVED_FROM_STAGE и когда он срабатывает подчищать все, что навешано на объект

dimarik 06.05.2011 12:56

Если из списка отображения (Display List, DL) удаляется узел, то все иерархически связанные с ним дети, внуки и правнуки и т.д. удалятся (будут garbage collected) при условии отсутствия ссылок на объекты этой ветки из внешних объектов.

Если, например, хотя бы один объект в ветке будет подписан на события Stage, то вся ветка будет жить.
Каким образом?

Предположим, что контейнер (условно, Depth_0) находится в списке отображения, содержит одного ребенка (Depth_1) и тот подписан на события мыши от Stage. Ребенок в свою очередь имеет другого ребенка (Depth_2). Метод-хендлер объекта Depth_1 зарегистрирован в качестве приемника события MouseEvent в Stage (Depth_1 исполнил код super.stage.addEventListener(MouseEvent.CLICK, this.handler_click)). Ссылка на этот метод (handler_click) находится во внутреннем массиве (Array) _listeners объекта Stage. Теперь удаляем Depth_0 из DL. Ни один уважающий себя (Garbage Collector, GC) при таком раскладе не удалит объект Depth_1. Итак, Depth_1 будет жить.

Как же будет жить его родитель (Depth_0)? У ребенка есть ссылка на родителя в поле parent. Родитель будет жить.

Как будет жить Depth_2 -- дитя Depth_1? У Depth_1 есть список детей и ссылка на Depth_2 находится в этом списке.


Для каждого объекта можно добавлять слушатель Event.REMOVED с проверкой на event.eventPhase === AT_TARGET или event.target === event.currentTarget. Это означает, что ребенок лишился своего непосредственного родителя. При выполнении одного из этих условий можно освобождать слушателей ребенка во внешних вещателях.

Если хендлер и источник -- находятся в одном и том же объекте, то иногда можно не отписываться от самого себя же. События, генерируемые действиями пользователя, такие как взаимодействие с мышью, клавиатурой, при потере фокуса (следствие удаления объекта из DL), и некоторые внутренние (Event.RENDER), перестанут генерироваться. Остальные внутренние события: ENTER_FRAME, EXIT_FRAME, FRAME_CONSTRUCTED, ACTIVATE, DEACTIVATE продолжат генерироваться до момента срабатывания GC.


Недостатком отписки от событий по REMOVED_FROM_STAGE является следующее: если мы захотим переместить ветку дисплей объектов на другой узел, последует лавинообразное удаление слушателей, а затем их добавление. Ведь при перемещении ветки происходит последовательное её удаление из DL, а затем добавление в DL. Cработают все её слушатели события REMOVED_FROM_STAGE и ADDED_TO_STAGE.

Недостатком отписки от событий по Event.REMOVED следует признать необходимость по-объектного удаления детей сверху вниз, от кроны к корню.

Zebestov 06.05.2011 13:15

А вообще при добавлении слушателя устанавливай useWeakReference в true (доки) и он не сможет препятствовать удалению объекта.

expl 07.05.2011 00:23

Только вот пока до него доберется GC, объект будет исправно грузить проц таймерами и обработкой событий ON_ENTER_FRAME,
ну обработкой этих самых событий, которые по weak-reference подписаны

А если обработка этих событий на что-то влияет, а объект уже где-то сверху считают мертвым - то теоретически можно получить ещё и баги (теоретически, потому что не могу вспомнить конкретных случаев)

fisher_it_i 10.05.2011 14:02

А вот скажите уважаемые можно ли из предназначенного для удаления экземпляра не вникая в цикле найти все навешаные на него лисенеры? Ну такая универсальная функция "Cleaning" на все случаи жизни?

ChuwY 10.05.2011 15:03

Если переопределить метод addEventListener и записывать все слушатели в массив, а потом удалять их при вызове этой функции, то можно.

Подобная тема обсуждалась где-то тут где-то чуть меньше бесконечности раз.


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

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