"Warning: 1090: Migration issue" 尽管显式注册了事件处理程序

"Warning: 1090: Migration issue" despite explicitly registering event handlers

我有一个游戏引擎 class 继承自 MovieClip 并在私有实例方法中处理 mouseDown 事件。为了简单起见,我将事件处理程序命名为 onMouseDown。它看起来像这样:

private function onMouseDown(e:MouseEvent):void
{
    if (_isEnginePlaying)
    {
        _player.attack();
    }
}

我在引擎 class 的 init 方法(本身是一个 addedToStage 处理程序)中注册它,如下所示:

private function init(e:Event):void
{
    removeEventListener(Event.ADDED_TO_STAGE, init);
    // ...
    stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
    // ...
}

这可以正确编译和工作,但编译器警告:

Warning: 1090: Migration issue: The onMouseDown event handler is not triggered automatically by Flash Player at run time in ActionScript 3.0. You must first register this handler for the event using addEventListener ( 'mouseDown', callback_handler).

但是,如图所示,我确实使用addEventListener()注册了处理程序。为什么编译器仍然发出此警告,我该怎么做才能使警告消失?

这是因为处理程序是在不同的实例而不是游戏引擎实例中注册的 (this)。请记住,AS2 中的事件处理程序只是通过将它们指定为实例的属性来注册的,这些实例应该处理相应的事件,并在需要时自动触发。那里的警告是为了通知开发人员他们不会在 AS3 中自动触发。

所以编译器出于谨慎而犯了错误,假设我正在尝试向游戏引擎实例注册一个点击处理程序(即使我已经在舞台上注册了它)并警告我这个效果。

有多种方法可以使警告消失:

  1. 只需重命名 onMouseDown 处理程序。 "on-" 约定是 AS2 的延续,编译器只对遵循此命名约定的处理程序发出警告;如果您愿意接受不同的约定,这是推荐的解决方案。 Adobe 使用的约定是“-Handler”(来源 1 2 3),因此 onMouseDown 变为 mouseDownHandler:

    private function init(e:Event):void
    {
        removeEventListener(Event.ADDED_TO_STAGE, init);
        // ...
        stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
        // ...
    }
    
    private function mouseDownHandler(e:MouseEvent):void
    {
        if (_isEnginePlaying)
        {
            _player.attack();
        }
    }
    
  2. 如果this可以侦听事件,则用this注册事件:

    private function init(e:Event):void
    {
        removeEventListener(Event.ADDED_TO_STAGE, init);
        // ...
        addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
        // ...
    }
    

    如果 意图 是为了 this 侦听事件,则使用不同的实例注册处理程序是不合适的。

  3. 如果您需要用不同的实例注册处理程序,但您确定定义在它应该在的位置,则必须重命名处理程序。如果出于某种原因更改所有事件处理程序的命名约定不是一种选择,那么您至少应该做的是在您注册它的任何名称前加上前缀,所以很明显这个处理程序不打算注册this,但实例不同:

    private function stage_onMouseDown(e:MouseEvent):void
    {
        if (_isEnginePlaying)
        {
            _player.attack();
        }
    }
    
  4. 如果你坚持让事情保持原样,你可以 suppress the warning altogether,但显然这不是你应该做的事情,除非你有充分的理由。