Recientemente he estado experimentando con las posibilidades del API de introspección y Reflexión de ActionScript 3 y me he encontrado con un problema inesperado: se produce un error al tratar de crear mediante reflexión un objeto de una clase que no se instancia explícitamente en ninguna otra parte del código de la aplicación.
El mensaje de error en estos casos suele ser algo como Error #1065: No se ha definido la variable MyClass.
Se trata de un problema de classloading y se debe a que el compilador de Flex no incluye en el archivo SWF las clases que no se referencian explícitamente en el código.
Por ejemplo, el siguiente código fallará a menos que la clase MyClass se utilice en alguna otra parte:
import com.softwarepills.MyClass;
var clazz:Class = getDefinitionByName("com.softwarepills.MyClass") as Class;
var instance:Object = new clazz();
A pesar de utilizar import, el SWF resultante no incluye la clase MyClass.
Para que el compilador incluya la clase es necesario utilizarla como en:
import com.softwarepills.MyClass;
var clazz:Class = getDefinitionByName("com.softwarepills.MyClass") as Class;
var instance:MyClass = new clazz() as MyClass;
Si, esto si funciona, pero si usamos reflection es porque, precisamente, no queremos incluir una referencia explícita a la clase.
Buscando en la Red he encontrado varias soluciones[1]. Una consiste en utilizar en una variable "dummy" en un punto arbitrario del código, por ejemplo:
import com.softwarepills.MyClass; var dummy:MyClass = new MyClass();
Este sistema no me gusta porque puede llevar a confusión y, además, es demasiado código para tan poca cosa.
El segundo método que se menciona consiste en crear un librería SWF con todas las clases que necesitamos y compilar la aplicación con ella, pero esto me parece demasiado aparatoso y propenso a errores.
Investigando un poco más he encontrado la que me parece la solución "menos mala", que consiste en utilizar un bloque de código estático como en el siguiente ejemplo:
import com.softwarepills.MyClass;
import com.softwarepills.MyOtherClass;
{MyClass,MyOtherClass}
Esta es para mi la forma mas compacta y menos aparatosa; se trata de enumerar las clases dentro de un bloque estático en cualquier cualquier fichero .as o .mxml de la aplicación.
¿No sabias que existía un bloque estático de código? Yo tampoco. Lo encontré en un artículo de insideria.com, donde también puedes enterarte de otras formas de trabajar con código estático o de incialización.
Tags: as3, classloading, Flex, reflection, static
Entradas (RSS)
Tu solucion es bastante valida. En lo personal me gusta utilizar un swf separado usando RSL ya que le da un sentido mas real por el cual usar reflection (ademas que puede ayudar a bajar el ancho de banda de nuestras aplicaciones) y brindando la opcion que con un uso correcto de reflection + interfaces + rsl podemos cargar nuevas clases a nuestras aplicaciones mejoradas o con nueva funcionalidad compilando solamente nuestra libreria y sin tener que compilar nuestra aplicacion principal, todo con la magia del dynamic linking
Aqui algo de informacion que puede servir de mas http://www.jamesward.com/blog/2007/02/19/faster-flex-applications-shrink-your-rsls/
saludos, excelente blog