удалите ENTER_FRAME EventListener из этого as3 - PullRequest
3 голосов
/ 15 марта 2012

Это мой код во Flash / AS3, в основном классе.

addEventListener(Event.ENTER_FRAME,function(e:Event){

        if(findObject == true){
            // I want to remove this ENTER FRAME
        }

});

Ответы [ 5 ]

13 голосов
/ 15 марта 2012

попробуйте это:

e.currentTarget.removeEventListener(e.type, arguments.callee)
5 голосов
/ 20 июля 2012
  1. Вы не должны делать то, что делаете в приведенном выше коде.

  2. У кода mgraph есть небольшая вероятность того, что он не будет работать так, как рекламируется, еслиУ currentTarget события нет метода removeEventListener() (возможно, но очень маловероятно).Однако с точки зрения компилятора вы будете пытаться динамически разрешать метод для универсального объекта, который подвержен ошибкам и должен обрабатываться с осторожностью.Это опасно, потому что показывает, что программист «не знал», какой объект он ожидал обработать, и работал по предположению.Предположения хороши для нахождения решения, но одинаково плохи для его реализации.

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

Если вы делаете это в качестве эксперимента, это нормально, но вам следует избегать такого кода впроекты в реальной жизни.

Еще одна вещь, о которой следует знать: сравнение с константой true на 100% бесполезно.Если такое сравнение имеет какой-либо смысл (т. Е. findObject может в любое время оценить false), тогда if (findObject) { ... } является эквивалентной, но более короткой версией вашего кода.Последнее, надеюсь, в анонимной функции отсутствует объявление типа возвращаемого значения.Это не сильно изменится в вашем примере, за исключением того, что вы получите предупреждение компилятора.Опущение объявления типа, как правило, является плохим стилем.

EDIT

public function addEventListener(type:String, listener:Function ...):void
{
    this._listeners[type].push(listener);
}

public function dispatchEvent(event:Event):void
{
    for each (var listener:Function in this._listeners[event.type])
        listener(event);
}

public function removeEventListener(type:String, listener:Function, ...):void
{
    delete this._listeners[type][listener];
}

Предположим, что вы действительно хотите реализовать IEventDispatcher (вместо использования другого EventDispatcher - вы можетеу вас есть для этого причины, одна из таких причин заключается в том, что встроенный EventDispatcher генерирует безумное количество недолговечных объектов - событий, и вы можете захотеть его уменьшить.) Но вы не можете реплицировать event.target или event.currentTurget вваш код, потому что вы не можете получить доступ к объекту, владеющему методом, поэтому вы бы не указали это.

Другой пример:

public class SomeEvent extends Event
{

    private var _target:NotEventDispatcher;

    public function SomeEvent(type:String, someTarget:NotEventDispatcher)
    {
        super(type);
        this._target = someTarget;
    }

    public override function get target():Object
    {
        return this._target;
    }
}

Это то, что я на самом деле видел в реальном мире.это использовалось либо в Mate, либо в аналогичной среде для «анонимного» подключения всех диспетчеров событий к одному статическому экземпляру некоторого «диспетчера событий материнского судна».

Я не обязательно оправдываю этот подход, нотехнически ничто не мешает вам сделать одно из этих действий.То, что я говорил в моем посте выше, это то, что в определенных ситуациях язык обещает вам такие вещи, как если бы вы сделали:

var dispatcher:IEventDispatcher;
try
{
    dispatcher = IEventDispatcher(event.currentTarget);
    // now you can be sure this object has removeEventListener
    dispatcher.removeEventListener(event.type, arguments.callee);
}
catch (error:Error)
{
    // but what are you going to do here?
}

Но наиболее распространенным случаем будет ваша подписка на пузырящее событие, в которомВ этом случае вы не знаете, хотите ли вы отписаться от event.target или event.currentTtarget, потому что не знаете, какой из них вы слушаете.

1 голос
/ 22 июля 2012

Я согласен с wvxvw.

Другим способом решения вашей проблемы является наличие переменной для управления «состоянием» вашего события ENTER_FRAME:

private var _state:String;

private function init(e:Event):void {
    addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
}

private function loop(e:Event):void {
    switch(_state) {
        case "play":
            // do play stuff
            // when you want to pause
            // goToPause();
        break;
    }
}

// you can call the method below from a button or whatever you want
private function goToPause():void {
    _state = "pause";
    // do some stuff here
    // when you are done, switch "_state" back to "play"
}

В этом примере вы продолжаете слушать ENTER_FRAME, но он работает только тогда, когда переменная _state установлена ​​в «play». Вы также можете удалить прослушиватель событий в методе goToPause:

private function goToPause():void {
    _state = "pause";
    removeEventListener(Event.ENTER_FRAME, loop);
}

Тем не менее, хорошая вещь об использовании "_state" для переключения вещей состоит в том, что у вас не будет беспорядка addEventListeners и removeEventListeners (что может случиться в зависимости от сложности вашего цикла), что вам нужно следить за.

0 голосов
/ 27 июля 2012

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

var callback:Function;
var dispacher:IEventDispatcher = this;
addEventListener(Event.ENTER_FRAME, callback = function(e:Event){

        if(findObject == true){
            dispacher.removeEventListener(Event.ENTER_FRAME, callback);
        }

});

Нормально закрытоприменяются правила переменной.

0 голосов
/ 23 июля 2012

Вам не следует использовать анонимный вызов функции, если вы хотите удалить слушателя через некоторое время.

public function main():void
{
    //...
    //some method, where you add event listener
    //...

    //adding enterFrame event listener
    this.addEventListener(Event.ENTER_FRAME,enterFrameHandler);

    //...

}

private function enterFrameHandler(e:Event)
{

    if(findObject)  // " == true" is not really necessary here.
    {
        // removing enterFrame listener:
        this.removeEventlistener(Event.ENTER_FRAME,enterFrameHandler);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...