![]() |
|
||||||||||
|
|||||||
|
|
« Предыдущая тема | Следующая тема » |
| Опции темы | Опции просмотра |
|
![]() |
![]() |
|
|||||
|
Регистрация: Jan 2010
Сообщений: 211
|
Допустим, есть такой код:
private function someFunction(param:int):void { ... var animate:Animate = new Animate(); ... animate.addEventListener(EffectEvent.EFFECT_END, someHandler); ... } protected function someHandler(event:EffectEvent):void { (event.target as Animate).removeEventListener(EffectEvent.EFFECT_END, someHandler); //some action } Если необходимо передать параметр в хандлер, то (на мой взгляд) наилучшим решение является следующее (можно использовать вариацию, переписав конструктор): private function addArguments(method:Function, additionalArguments:Array):Function { return function(event:Event):void {method.apply(null, [event].concat(additionalArguments));} } ... private function someFunction(param:int):void { ... var animate:Animate = new Animate(); ... animate.addEventListener(EffectEvent.EFFECT_END, addArguments(someHandler, [param])); ... } protected function someHandler(event:EffectEvent, param:int):void { (event.target as Animate).removeEventListener(EffectEvent.EFFECT_END, someHandler); //вот тут //some action } или ? Спасибо. |
|
|||||
|
Ни то, ни другое.
Прежде всего - такой способ передачи параметров в обработчик является дурным тоном. Обработчик должен обрабатывать только событие, а не событие и параметр. У события, как правило, достаточно свойств, чтобы обработчик смог выполнить необходимое действие. Если же мои слова звучат неубедительно и вам хочется использовать этот способ, то для отписки от события вам прийдется: а) сохранить ссылку на анонимную функцию, возвращаемую вашим addArguments; б) использовать arguments.callee из тела вашей анонимной функции; в) передавать arguments.callee из тела вашей анонимной ф-и в ваш обработчик. а: var handler:Function; handler=addArguments(someHandler,[param]); animate.addEventListener(EffectEvent.EFFECT_END,handler); ... removeEventListener(EffectEvent.EFFECT_END,handler); private function addArguments(method:Function, additionalArguments:Array):Function { return function(event:Event):void { method.apply(null, [event].concat(additionalArguments)); event.currentTarget.removeEventListener(event.type,arguments.callee); } } private function addArguments(method:Function, additionalArguments:Array):Function { return function(event:Event):void { method.apply(null, [event].concat(additionalArguments),arguments.callee); } } protected function someHandler(event:EffectEvent, param:int,handler:Function):void { event.currentTarget.removeEventListener(EffectEvent.EFFECT_END, handler); //вот тут //some action } PS вызывать removeEventListener нужно именно у event.currentTarget, потому что в target может быть что угодно, а в currentTarget - именно объект, который диспатчит событие. |
|
|||||
|
Регистрация: Jan 2010
Сообщений: 211
|
Огромное спасибо ... нет слов.
Правда, возникают вопросы ... По поводу дурного тона спорить не буду, думаю, что даже согласен. Просто не хочется создавать кастомное событие, которое бы содержало хранимые параметры (даже не знаю почему), а штатные средства так делать не могут. Поэтому такой вариант мне кажется вполне удобоваримым. Второй вариант действительно облегчает жизнь - не нужны лишние вызовы и удаление будет под контролем. Правда, возникает вопрос к третьему варианту: хандлер - статическая функция (в смысле, что не создается динамически, а не имеет ключевое слово атрибута static), и arguments.callee будет равно someHandler, то есть параметр handler у функции будет указывать на саму функцию. То есть несколько абсурдна запись - это раз, а второе - если следовать логике, то мой первый вариант правильный. P.S. 50 на 50, что ошибаюсь и все легко проверяется трейсами в коде, но как-то сейчас рука не поднимается этим заниматься ![]() |
|
|||||
|
В третьем варианте arguments.callee предается из анонимной функции и указывает именно на нее, а не на someHandler.
Добавлено через 3 минуты Он, в принципе, аналогичен второму варианту, только отписка происходит не в анонимной функции, а в вашем обработчике. Этот вариант позволит вам контролировать отписку от события, т.е. - отписаться не сразу после события, а по какому-то условию. |
|
|||||
|
Регистрация: Jan 2010
Сообщений: 211
|
Проверка очень проста. Использовал второй вариант и:
protected function someHandler(event:EffectEvent, i:int):void { Alert.show("" + (event.currentTarget as Animate).hasEventListener(EffectEvent.EFFECT_END)); (event.currentTarget as Animate).removeEventListener(EffectEvent.EFFECT_END, someHandler); Alert.show("" + (event.currentTarget as Animate).hasEventListener(EffectEvent.EFFECT_END)); (event.currentTarget as Animate).removeEventListener(EffectEvent.EFFECT_END, addArguments(someHandler, [i])); Alert.show("" + (event.currentTarget as Animate).hasEventListener(EffectEvent.EFFECT_END)); } Добавлено через 8 минут ... Или это GC еще не добрался до них (него) и событие все еще висит ... пока? |
|
|||||
|
Регистрация: Jan 2010
Сообщений: 211
|
Точно! Обидно на таких вещах прокалываться. Еще раз огромное спасибо!
Зато для себя убедился, что оба моих варианта однозначно нерабочие. |
![]() |
![]() |
Часовой пояс GMT +4, время: 00:02. |
|
|
« Предыдущая тема | Следующая тема » |
| Опции темы | |
| Опции просмотра | |
|
|