About

<#TEMPLATE_INCLUDE_NINEPAGE_ABOUTME#>
  • Oct

    23

    1、注入点不起作用

    正确的样例代码:

    [Inject]
    public var someValue:SomeType;

    Inject 区分大小写,中括号后不能有分号,注入对象引用的修饰词必须是public(违反这些规则时编译器是不会报错的,但注入不会起作用)。

    2、元标签代码部份被剥离

    Flash / Flex 编译器会跳过不标准的元数据(所谓的元数据,其实就是指在编译阶段编译器可识别的特殊指令,不属于编译后代码的一部份),[Inject] 与 [PostConstruct] 都不属于 Flex 标准的元数据,它们都是开发者自定义的元数据。

    所以 Robotlegs 最好是使用它的现成 SWC “库文件”,而不是使用 AS “源文件”,因为库文件已经是预编译的代码,这些代码本身被编译器所需要的元数据所编译(如果使用了源代码的方式进行编译,它在调试模式时可能按原样方式输出,在发布 release 版本时这些代码会被全部剥离,变成无效代码)。

    如果一定要使用源代码的方式,那么需要按着如下方式:

    a:在 Flex 的项目属性里为编译器添加如下参数:

    -keep-as3-metadata+=Inject -keep-as3-metadata+=PostConstruct

     b:如果使用Flash IDE,要在发布设置中勾选“导出 SWC”文件(这样会强制 Flash 编译器)。

    3、在构造函数中访问的注入对象为 null

    不要在构造函数中直接使用注入对象的引用(因为这时候它们还没有被实例化,如果访问它们都会是null)。

    a、最常用的解决方法是从构造函数中删除这些访问注入对象的代码,把它们放在一个单独的函数中,并且使用一个 PostConstruct 元标签:

    [PostConstruct]
    public function init():void
    {
        //all dependencies have now been satisfied
        //这里就可以访问所有依赖注入的对象
    }

    b、Robotlegs 使用构造注入解决方案取代 属性与setter 对象注入,并且不要在构造函数中启动或执行任何复杂的业务。

    4、执行了一会儿意外停止

    比如下面的代码就有可能运行一会儿,然后意外停止,因为它使用的是一个局部变量,就有可能在垃圾回收时被回收掉了。需要改为使用一个实例变量始终引用这个上下文背景(context)对象。

    public class HelloActionScript extends Sprite
    {
        public function HelloActionScript()
        {
            var context:HelloContext = new HelloContext( this );
        }
    }

    5、Event Dispatch 调度事件时不起作用

    创建自定义事件时一定要,必须要,务必要重写 clone() 方法(发现很多人自定义事件时都不重写这个方法,包括 toString() 其实作为一种 AS 自定义事件时的编程习惯,都必须重写它们),clone() 方法是复制和转发事件所必须的(除非你这辈子不进行事件的复制与转发)。

    6、Mediator 对象没有实例化

    a:确认已经创建了映射;

    b:确认是否已经被添加到舞台;

    c:确认是先添加映射再被添加到舞台,而不是先添加到舞台再映射;

    d:确认是直接被添加到舞台的,添加后的 stage 属性是直接可以访问的(而不是先添加到一个没有舞台引用的父对象,再通过父对象添加)。

    7、访问未定义的方法

    如下样例代码:

    package controller 
    {
        import model.MyModel;
        import org.robotlegs.mvcs.Command;

        public class MyCommand extends Command
        {
            [Inject]
            public var model:MyModel;

            [Inject]
            public var event:MyEvent;

            override public function execute():void
            {
                model.myMethod();
            }
        }
    }

    有没有注意到上面有一个包是“model.MyModel;”?包路径中就带了一个 model。还有没有注意到一个实例变量是“var model:MyModel;”?也存在一个 model。开发人员的意图很可能是想访问一个 Model 实例myMethod() 方法,但编译器认为你想访问的是一个 model 包中一个名为 myMethod() 的全局方法。

    虽然代码在运行时作用域是由内而外的执行,先检查局部变量,再检查实例变量,再检查静态变量等等;但编译器编译代码时是如果发现你的变量定义与包名相同,它首先会使用最外部的包名,而不是代码中的定义。

    8、缺少注入映射

    还是一样,先看代码:

    injector.mapSingletonOf(ISomeType, SomeType);
    injector.mapSingletonOf(BaseSomeType, SpecialSomeType);

    在使用 mapSingletonOf() 这个方法后,第一个参数是一个映射类,而不是具体的类。

    比如下面这样子是正确的:

    [Inject]
    public var someValue:ISomeType;

    [Inject]
    public var someOtherValue:BaseSomeType;

    但下面这样直接使用具体的类就错了:

    [Inject]
    public var someValue:SomeType;

    [Inject]
    public var someOtherValue:SpecialSomeType;

    原文地址github.com/robotlegs/robotlegs-framework/wiki/Common-Problems