Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Работа с событиями, Удаление отработавших слушателей 
V
    Опции темы
Simplifier
Дата 27.4.2012, 16:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 26
Регистрация: 18.7.2011

Репутация: нет
Всего: нет



Есть ли возможность и требуется ли в яве отписываться от отработавших слушателей?
В as3 принято всегда отписываться от слушателя события после того, как оно наступило. Например, если мы прослушиваем завершение загрузки некоторого объекта, то от этого события следует отписаться, как только загрузка будет завершена:
Код

package source{
    import flash.display.*;
    import flash.events.Event;
    import flash.net.URLRequest;
    import flash.system.LoaderContext;
    public class Content extends Sprite {
        private var loader:Loader = new Loader;
        private var request:URLRequest = new URLRequest;
        
        public function Content():void {
            //constructor
        }
        
        public function load(src:String):void {
            try {
                loader.close();
            }catch (e:Error) { }
            
            request.url = src;
            loader.load(request);
            //регистриуем слушатель completeHandler
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
        }
        
        private function completeHandler(e:Event):void {
            //отписываемся от completeHandler`а
            loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, completeHandler);
            //обрабатываем загруженный объект доступный через loader.content
        }
    }
}

Дело в том, что если не отменять регистрацию слушателя после использования, то он так и останется висеть в оперативке, естественно, вместе со своим контекстом, ожидая повторного наступления события. Кроме того, сборщик мусора не удалит объект на котором подвешено событие, даже после того как занулишь все ссылки на этот объект. Вопрос, как обстоит с этим дело в java?
PM MAIL   Вверх
aleksandy
Дата 28.4.2012, 09:00 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 260
Регистрация: 17.12.2006

Репутация: 4
Всего: 5



Возможность есть: SomeClass.removeXXXListener(XXXListener)

Не понимаю смысла подписывания на событие, если оно 100% одноразовое.
PM   Вверх
dorogoyIV
Дата 28.4.2012, 12:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1503
Регистрация: 26.3.2007

Репутация: 3
Всего: 46



Цитата(Simplifier @  27.4.2012,  16:25 Найти цитируемый пост)
Дело в том, что если не отменять регистрацию слушателя после использования, то он так и останется висеть в оперативке, естественно, вместе со своим контекстом, ожидая повторного наступления события. Кроме того, сборщик мусора не удалит объект на котором подвешено событие, даже после того как занулишь все ссылки на этот объект. 

можно насчет этого не заморачиваться.
уже давно оперативка на компах не 32 Кб, а намного больше!

PM MAIL   Вверх
Simplifier
Дата 28.4.2012, 14:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 26
Регистрация: 18.7.2011

Репутация: нет
Всего: нет



Спасибо) Протупил, действительно, надо было просто в хелп заглянуть и все) Просто когда учебник читал, не нашел, чтоб отписывание от обработчиков использовалось и не стал даже в доки заглядывать. А зря((
Цитата(aleksandy @ 28.4.2012,  09:00)

Не понимаю смысла подписывания на событие, если оно 100% одноразовое. 

В as3 события используются очень широко, там вообще нет блокирующих операций. Жизненный цикл всех сокетов, лоадеров, проигрывание аудио/видео и тд и тп отслеживается через события. Удобно, в общем-то) В яве события, по ходу, намного меньше распространены.
Цитата(dorogoyIV @ 28.4.2012,  12:32)

можно насчет этого не заморачиваться.
уже давно оперативка на компах не 32 Кб, а намного больше!

Ну эт да) Но такого ж мусора может до фига накопиться) Да и не только оперативка может забиваться, но и процессор. Если, например, создать несколько визуальных объектов и один таймер. И в каждом объекте подписаться на тиканье этого таймера. И, к примеру, при каждом такте менять координаты объекта. Если нам понадобится удалить один из этих объектов, мы удалим его со сцены, занулим на него ссылку и тд. А слушатель-то так и останется. И будет по прежнему отрабатывать каждый такт, изменяя координаты этого объекта. Ну, и потреблять ресурсы процессора.

Это сообщение отредактировал(а) Simplifier - 28.4.2012, 14:29
PM MAIL   Вверх
Skynin
Дата 28.4.2012, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 359
Регистрация: 1.7.2007
Где: Харьков

Репутация: 6
Всего: 10



Цитата

Да и не только оперативка может забиваться, но и процессор.
...
А слушатель-то так и останется.
...
Ну, и потреблять ресурсы процессора.

Это да, флэша любит процессорное время сжирать, даже когда "ничего не делает".
У меня кулер на 4ядерном проце "голосом" сообщает - запустился где-то в браузере флеш! Как при конвертации видео, или в Alice Madness Return во время боя. В простое в Alice меньше шума чем от флеша.
А ноут - видать феном стать мечтает, когда с флешой сталкивается.
Так и не понял, почему программистам из Adobe не удается отлавливать "простой", а не гонять что-то в движке усиленно в цикле...

В Java слушатель мертвого объекта процессорного времени не потребляет. Да и живого, пока тот собственно не вызовет метод слушателя.

Правда, так как он содержит в себе ссылку на прослушиваемый объект, то тот не будет собран, пока не отпишешься от событий.
Или на него самого нет ссылки - то оба будут собран сборщиком мусора.
Всегда нужно помнить - слушатель держит в памяти того кого слушает, пока не отпишешься.

Цитата
В яве события, по ходу, намного меньше распространены.

потому что слушатель - это один из многих паттернов. И вовсе не универсальный и идеальный.
Но в системной библиотеке, и фреймворках вполне распространен.

Цитата
В as3 принято всегда отписываться от слушателя события после того, как оно наступило.

Действительно странный подход...

В java подписываются на события если нужно слушать многократно, регулярно, а не 1 раз.
А для одного раза есть и проще способы.


Это сообщение отредактировал(а) Skynin - 28.4.2012, 17:01
PM MAIL WWW ICQ Skype GTalk YIM MSN   Вверх
Simplifier
Дата 28.4.2012, 18:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 26
Регистрация: 18.7.2011

Репутация: нет
Всего: нет



Цитата

Это да, флэша любит процессорное время сжирать, даже когда "ничего не делает".

Мм.. Нет, флеш во время простоя тоже не потребляет процессорное время. Видимо, вы говорите про флеш баннеры. Во-первых, баннеры обычно напиханы анимацией под завязку, а анимирование графики как раз потребляет немало процессора. Это не есть "ничего не делает". Во-вторых, их делают ни разу не программисты, а баннермейкеры, которых качество кода ни капли не заботит. Отсюда и результат. И, кстати, для экономии ресурсов рендеринг графики отключается через некоторое время, если вкладка с флешкой неактивна. http://habrahabr.ru/post/96180/
Цитата(Skynin @  28.4.2012,  16:33 Найти цитируемый пост)
Цитата
В as3 принято всегда отписываться от слушателя события после того, как оно наступило.

Действительно странный подход...

Почему странный? Я имел ввиду отписываться, когда событие уже больше не наступит или нам больше не нужно его перехватывать. Если мы, например, подвесили листенер на кнопку и нам надо, чтобы клик по ней обрабатывался все время пока запущена программа, то, конечно, отписываться незачем. А если, событие генерируется лишь конечное число раз, то после генерации последнего раза от него можно отписаться, так как пользы от него больше нет. Например, мы создали таймер, который после запуска сгенерирует событие 3 раза с интервалом 2 сек. После 3го такта мы от события отпишемся. (В as3 в этом случае после генерации 3х событий timer будет сгенерировано событие timerComplete, в котором удобно удалить регистрацию слушателя)

Цитата(Skynin @  28.4.2012,  16:33 Найти цитируемый пост)
В java подписываются на события если нужно слушать многократно, регулярно, а не 1 раз.
А для одного раза есть и проще способы.

Ну, другие способы, конечно, есть, но и подписывание на событие не назовешь сложным
Это в java работа событиями довольно сложна. Чтобы обработать событие, надо создать целый класс, который для разных событий должен реализовывать разные интерфейсы. С разным набором методов. Если нужны не все из этих методов, а только часть, то следует уже расширять класс-адаптер, а не интерфейс. И имена методов для регистрации разных типов событий тоже разные.
В as3 работа с событиями более стандартизирована и устроена проще. Чтобы зарегистрировать обработчик, его вместе с со строковым именем прослушиваемого события (и дополнительными необязательными параметрами, если требуется) передают методу со стандартным именем addEventListener. Для создания обработчика не надо писать отдельный класс, который что-то будет расширять. Так как в as3 можно передавать функции по ссылке, то листенер является методом, а не объектом. Единственное ограничение, налагаемое на листенер, состоит в том, что он принимает параметром объект события.

Это сообщение отредактировал(а) Simplifier - 28.4.2012, 18:52
PM MAIL   Вверх
COVD
Дата 28.4.2012, 19:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 17
Всего: 43



Цитата

Это в java работа событиями довольно сложна.... 

Очевидно, в других технологиях часть рутинной работы выполняется за сценой. Это упрощает программирование, но возможно маскирует суть. А суть "подписки" одна - в коллекцию добавляется обьект-лисенер. "Выписка" - из коллекции удаляется обьект-лисенер. Обьект-лисенер - это любой обьект с заранее известным методом. Не принципиально, обьект или ссылка на метод. Принципиально, что в коллекцию нечто однородного.

Это сообщение отредактировал(а) COVD - 28.4.2012, 19:18
PM MAIL   Вверх
Simplifier
Дата 28.4.2012, 19:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 26
Регистрация: 18.7.2011

Репутация: нет
Всего: нет



Ну, суть естественно одна. Никто не спорит) Единственное заметное различие в том, что в as3 в коллекцию вместо обьекта-лисенера добавляется метод-лисенер.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1184 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.