Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 16.10.2009, 01:28
bjd вне форума Посмотреть профиль Отправить личное сообщение для bjd Найти все сообщения от bjd
  № 1  
Ответить с цитированием
bjd

Регистрация: Mar 2007
Адрес: Киев
Сообщений: 96
Question Как управлять слушателями?

Подскажите, пожалуйста, наиболее простой и эффективный способ удаления обработчиков событий, созданных в экземплярах классов? Возможно, ли передавать ссылки на созданные слушатели в специально предназначенный для этого класс и при необходимости пройтись по ссылкам и удалить все слушатели? Если да, подскажите, как это реализовать? А если нет, то подскажите альтернативу...

Старый 16.10.2009, 01:53
FX2000 вне форума Посмотреть профиль Отправить личное сообщение для FX2000 Найти все сообщения от FX2000
  № 2  
Ответить с цитированием
FX2000

Регистрация: Sep 2009
Сообщений: 39
Удалить, например, addEventListener(Event.ENTER_FRAME, doSmth); можно с помощью
removeEventListener(Event.ENTER_FRAME, doSmth);

Старый 16.10.2009, 02:14
Lecosson вне форума Посмотреть профиль Отправить личное сообщение для Lecosson Найти все сообщения от Lecosson
  № 3  
Ответить с цитированием
Lecosson

Регистрация: Apr 2008
Сообщений: 80
Записей в блоге: 3
Я сделал иначе - во всех проектах использую свой Sprite, унаследованный от обычного спрайта, но с переопределенными методами (например, addEventListener).
Мой вариант имеет свой небольшой пул, куда складывает все имеющиеся в нем листенеры, слушает удаление себя, при этом убивает всех своих слушателей, детей и благополучно дохнет сам.
По возможности - слежу за удалением сам, но если где-то накосячу - мой класс сам себя подчистит. Кстати, помогает в отладке - при удалении спрайта со сцены сразу можно оттрейсить, где какой слушатель остался висеть.

Старый 16.10.2009, 02:19
bjd вне форума Посмотреть профиль Отправить личное сообщение для bjd Найти все сообщения от bjd
  № 4  
Ответить с цитированием
bjd

Регистрация: Mar 2007
Адрес: Киев
Сообщений: 96
Lecosson

Если не жалко, поделись примером или исходником...


Последний раз редактировалось bjd; 16.10.2009 в 13:42.
Старый 17.10.2009, 17:37
switcher! вне форума Посмотреть профиль Отправить личное сообщение для switcher! Найти все сообщения от switcher!
  № 5  
Ответить с цитированием
switcher!

Регистрация: May 2009
Сообщений: 220
bjd, лови.
Например, вот так:
Код AS3:
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);
			}
		}
    }
}

Старый 18.10.2009, 00:55
Lecosson вне форума Посмотреть профиль Отправить личное сообщение для Lecosson Найти все сообщения от Lecosson
  № 6  
Ответить с цитированием
Lecosson

Регистрация: Apr 2008
Сообщений: 80
Записей в блоге: 3
У меня почти то же самое:

Код AS3:
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);
}
}

Старый 18.10.2009, 01:50
bjd вне форума Посмотреть профиль Отправить личное сообщение для bjd Найти все сообщения от bjd
  № 7  
Ответить с цитированием
bjd

Регистрация: Mar 2007
Адрес: Киев
Сообщений: 96
Всем спасибо!

Старый 18.10.2009, 12:33
etc вне форума Посмотреть профиль Найти все сообщения от etc
  № 8  
Ответить с цитированием
etc
Et cetera
 
Аватар для etc

Регистрация: Sep 2002
Сообщений: 30,787
И никто из ответивших не проверяет, есть ли такой слушатель в массиве при добавлении или нет.

Старый 18.10.2009, 15:25
switcher! вне форума Посмотреть профиль Отправить личное сообщение для switcher! Найти все сообщения от switcher!
  № 9  
Ответить с цитированием
switcher!

Регистрация: May 2009
Сообщений: 220
по хорошему - надо бы ))
Это будет на совести программиста , чтобы не добавлял слушатель, когда он уже добавлен. Хз... я такие вещи четко держу в голове.
Однако, в команде, если не уверен в партнерах, или, наоборот, если хочешь снять с них заботу по слежению за слушателями - может пригодиться. Но и в этом случае по факту вторичного добавления слушателя - нужно генерить ошибку, чтобы потом эти непредусмотренные добавления не вышли боком.
Как-то так -)

Старый 18.10.2009, 18:43
etc вне форума Посмотреть профиль Найти все сообщения от etc
  № 10  
Ответить с цитированием
etc
Et cetera
 
Аватар для etc

Регистрация: Sep 2002
Сообщений: 30,787
По хорошему будет не писать больше подобных классов.

Создать новую тему Ответ Часовой пояс GMT +4, время: 21:48.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


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


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