![]() |
|
||||||||||
|
|||||
|
Регистрация: Mar 2007
Адрес: Киев
Сообщений: 96
|
Подскажите, пожалуйста, наиболее простой и эффективный способ удаления обработчиков событий, созданных в экземплярах классов? Возможно, ли передавать ссылки на созданные слушатели в специально предназначенный для этого класс и при необходимости пройтись по ссылкам и удалить все слушатели? Если да, подскажите, как это реализовать? А если нет, то подскажите альтернативу...
|
|
|||||
|
Регистрация: Sep 2009
Сообщений: 39
|
Удалить, например, addEventListener(Event.ENTER_FRAME, doSmth); можно с помощью
removeEventListener(Event.ENTER_FRAME, doSmth); |
|
|||||
|
Я сделал иначе - во всех проектах использую свой Sprite, унаследованный от обычного спрайта, но с переопределенными методами (например, addEventListener).
Мой вариант имеет свой небольшой пул, куда складывает все имеющиеся в нем листенеры, слушает удаление себя, при этом убивает всех своих слушателей, детей и благополучно дохнет сам. По возможности - слежу за удалением сам, но если где-то накосячу - мой класс сам себя подчистит. Кстати, помогает в отладке - при удалении спрайта со сцены сразу можно оттрейсить, где какой слушатель остался висеть. |
|
|||||
|
Регистрация: Mar 2007
Адрес: Киев
Сообщений: 96
|
Lecosson
Если не жалко, поделись примером или исходником... Последний раз редактировалось bjd; 16.10.2009 в 13:42. |
|
|||||
|
Регистрация: May 2009
Сообщений: 220
|
bjd, лови.
Например, вот так: package { import flash.display.Sprite; import flash.events.Event; public class Example extends Sprite { //массив со списком слушателей private var arr:Array = new Array(); function Example():void { addEventListener(Event.ADDED_TO_STAGE, addedToStage); } // переписываем оригинальную функцию public override function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void { super.addEventListener(type, listener, useCapture, priority, useWeakReference); //вызываем оригинальную (не override) функцию arr.push([type, listener]); //обновляем массив arr новым слушателем } public override function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void { super.removeEventListener(type, listener, useCapture); //вызываем оригинальную (не override) функцию var arr:Array = this.arr; //создаем локальную ссылку на массив, чтобы ускорить код в этой функции var len:int = arr.length; // проходимся по массиву от конца к началу, дабы удаление элементов не повлияло на актуальность операций for (var i:int = len-1; i >= 0; i--) { if (type === arr[i][0]) //если удаляемый тип слушателя найден... { arr.splice(i, 1); // удаляем весь элемент-массив (т.е. тип_слушателя_+_ссылка_на_функцию) } } } private function addedToStage(e:Event):void { addEventListener(Event.REMOVED_FROM_STAGE, removeListeners); removeEventListener(Event.ADDED_TO_STAGE, addedToStage); } private function removeListeners(e:Event):void { removeEventListener(Event.REMOVED_FROM_STAGE, removeListeners); var arr:Array = this.arr; //создаем локальную ссылку на массив, чтобы ускорить код в этой функции var len:int = arr.length; //Проходимся по всему списку массива сло слушателя и ВСЕХ их удаляем. for (var i:int = len-1; i >= 0; i--) { removeEventListener(arr[i][0], arr[i][1]); } addEventListener(Event.ADDED_TO_STAGE, addedToStage); while (this.numChildren > 0) // если у объекта есть дети, удаляем их { removeChildAt(0); } } } } |
|
|||||
|
У меня почти то же самое:
package MyPackage { import flash.display.Sprite; import flash.events.Event; public class MySprite extends Sprite { private var listenerPool:Array; // в этом массиве хранятся все события, на которые подписывается данный спрайт public function MySprite() { listenerPool=new Array(); super(); // добавляем слушатель на удаление спрайта - уничтожить при этом слушателей super.addEventListener(Event.REMOVED, removeAllEvents); } private function removeAllEvents(event:Event):void { if (event.target == this) //только если это событие удаления именно этого спрайта { super.removeEventListener(Event.REMOVED, removeAllEvents); while(listenerPool.length > 0) { var pool:Array=listenerPool.pop(); removeEventListener(pool[0], pool[1], pool[2]); } } } public override function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void { super.addEventListener(type, listener, useCapture, priority, useWeakReference); var pool:Array=new Array(); pool[0]=type; pool[1]=listener; pool[2]=useCapture; listenerPool.push(pool); } public override function removeEventListener(type:String, listener:Function, useCapture:Boolean=false):void { // эта функция удаляет слушатель спрайта и убирает его из массива слушателей super.removeEventListener(type, listener, useCapture); function removeListener(a:Object, index:int, source:Array):Boolean { if ((a[0] == source[index][0]) && (a[1] == source[index][1]) && (a[2] == source[index][2])) return (true); return (false); } listenerPool.filter(removeListener); } } |
|
|||||
|
Регистрация: Mar 2007
Адрес: Киев
Сообщений: 96
|
Всем спасибо!
|
|
|||||
|
Et cetera
Регистрация: Sep 2002
Сообщений: 30,787
|
И никто из ответивших не проверяет, есть ли такой слушатель в массиве при добавлении или нет.
|
|
|||||
|
Регистрация: May 2009
Сообщений: 220
|
по хорошему - надо бы ))
Это будет на совести программиста , чтобы не добавлял слушатель, когда он уже добавлен. Хз... я такие вещи четко держу в голове. Однако, в команде, если не уверен в партнерах, или, наоборот, если хочешь снять с них заботу по слежению за слушателями - может пригодиться. Но и в этом случае по факту вторичного добавления слушателя - нужно генерить ошибку, чтобы потом эти непредусмотренные добавления не вышли боком. Как-то так -) |
|
|||||
|
Et cetera
Регистрация: Sep 2002
Сообщений: 30,787
|
По хорошему будет не писать больше подобных классов.
|
![]() |
![]() |
Часовой пояс GMT +4, время: 22:48. |
|
|
« Предыдущая тема | Следующая тема » |
| Опции темы | |
| Опции просмотра | |
|
|