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

HardCoder 18.05.2011 22:51

Как удалить ссылку на приемник события
 
Вопрос такой: При использовании следующего кода
Код AS3:

                        mc.addEventListener(Event.ENTER_FRAME, function(e:Event):void {
                                        trace("warking");
                                });
                        mc.removeEventListener(Event.ENTER_FRAME, function(e:Event):void {
                                        trace("warking");
                                });

В output все время выводится "warking". Когда использую слабую ссылку и обнуляю обьект
Код AS3:

                        mc.addEventListener(Event.ENTER_FRAME, function(e:Event):void {
                                        trace("warking");
                                }, false, 0, true);
                        mc = null;

Все равно в output все время выводится "warking". Почему так? Проблема в том что сборщик мусора все еще не принялся за уничтожение? Или здесь есть нюанс немного по-серьезней?

ChuwY 18.05.2011 23:05

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

HardCoder 18.05.2011 23:11

Я знаю что их нельзя использовать и никогда так не делаю. Это так - спортивный интерес... Хочу знать, можно ли удалить такой слушатель или нет. И почему, когда делаю так:
Код AS3:

mc.addEventListener(Event.ENTER_FRAME, function(e:Event):void {trace("warking");}, false, 0, true);
mc = null;

ничего не меняется?

kseniya 18.05.2011 23:53

Код AS3:

mc.addEventListener(Event.ENTER_FRAME, mcFunc, false, 0, true);
function mcFunc(e:Event):void {
        trace("warking");
}
mc.removeEventListener(Event.ENTER_FRAME,mcFunc);


ChuwY 19.05.2011 00:15

Кроме прочего -- ты не удалил объект из дисплейлиста.
Если не удалять -- его и GC не подберет, так как ссылка на него все еще останется в паренте.

HardCoder 19.05.2011 00:28

Да я его даже и не добавлял...
Код AS3:

package {
        import flash.display.MovieClip;
        import flash.display.Sprite;
        import flash.events.Event;
 
        /**
        * ...
        * @author Tolik
        */

        public class NewClass extends Sprite{
                private var mc:MovieClip = new MovieClip();
 
                public function NewClass(){
                        mc.addEventListener(Event.ENTER_FRAME, function(e:Event):void {
                                        trace("warking");
                                }, false, 0, true);
                        mc = null;
                }
        }
}


Psycho Tiger 19.05.2011 00:40

Внутри этой функции можно.
Вот мой сниппет, часто пишу его когда надо отписаться после первого триггера события.
Код AS3:

if (event) (event.currentTarget as IEventDispatcher).removeEventListener(event.type, arguments.callee);


derhab 19.05.2011 00:48

Цитата:

Сообщение от ChuwY (Сообщение 997038)
Кроме прочего -- ты не удалил объект из дисплейлиста.
Как только ты оттуда его удалишь событие энтерфрейма перестанет диспатчиться.

с чего бы это?

HardCoder 19.05.2011 01:02

Нашел еще один вариант:
Код AS3:

mc.addEventListener(Event.ENTER_FRAME, function(e:Event):void {trace("warking");}, false, 0, true);
mc = null;
System.gc();


ChuwY 19.05.2011 01:07

Цитата:

Сообщение от derhab (Сообщение 997047)
с чего бы это?

Моя неправда.
Но если удалить в ту же фазу, что и добавляем, то не будет диспатча.
Меня это всегда сбивает с толку.

Добавлено через 1 минуту
Цитата:

Сообщение от HardCoder (Сообщение 997051)
Нашел еще один вариант:
Код AS3:

mc.addEventListener(Event.ENTER_FRAME, function(e:Event):void {trace("warking");}, false, 0, true);
mc = null;
System.gc();


Это будет работать только в дебаге, потому не стоит на то полагаться.
К тому же экстренный запуск GC не есть хорошо.

HardCoder 19.05.2011 01:22

Понял...
Psycho Tiger, жаль, что в вашем случае функция выполнится только один раз... Придется создавать некий маркер типа этого:
Код AS3:

private var mc:MovieClip = new MovieClip();
private var counter:uint = 0;
 
public function NewClass(){
        mc.addEventListener(Event.ENTER_FRAME, function(e:Event):void {
                        trace("warking");
                        counter++;
                        if (counter == 3){
                                e.currentTarget.removeEventListener(Event.ENTER_FRAME, arguments.callee);
                        }
                });
}

Хотя, ладно я и так зашел слишком далеко... Вывод: нечего использовать вложенные функции. Спасибо всем за внимание.


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

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