Hola otra vez, para dar solución a este tema que planteaba hace unos días, me he decidido a crear una clase llamada Propiedades siguiendo el patrón de diseño Singleton (para que no se puedan crear instancias de la clase, sino que haya sólo una).
En el código que pegaré a continuación, puede verse que una vez esté creada la instancia, se procede a cargar las propiedades del fichero propiedades.xml.
Además tengo otro método llamado getPropiedad(String) cuya misión es obtener el valor de la propiedad pasada como parámetro.
pongo el código de la clase y a continuación comento mi problema
Código ActionScript :
package
{
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLRequest;
/**
* ...
* @author Lorena
*/
public class Propiedades {
private static var instancia : Propiedades;
private static var v_propiedades : Array = null;
private static var permitidaInstancia : Boolean;
public function Propiedades() {
if (!permitidaInstancia) {
throw new Error("Debes usar getPropiedades()");
}else {
trace("Se inicializó una instancia de Propiedades");
if (v_propiedades == null) {
trace("El array de propiedades es null");
var loader : URLLoader = new URLLoader();
var request : URLRequest = new URLRequest("propiedades.xml");
loader.load(request);
loader.addEventListener(Event.COMPLETE, cargarPropiedades);
}else {
trace("Ya están todas las propiedades cargadas en el Array");
for (var s : String in v_propiedades) {
trace("propiedad " + s + "= " + v_propiedades[s]);
}
}
}
}
public static function getPropiedades() : Propiedades {
trace("Entro en getPropiedades()");
if (instancia == null) {
permitidaInstancia = true;
instancia = new Propiedades();
permitidaInstancia = false;
}else {
trace("se devuelve la instancia existente");
}
return instancia;
}
static private function cargarPropiedades(e:Event):void {
trace("Estoy en cargarPropiedades");
var loader : URLLoader = e.target as URLLoader;
var xmlExterno : XML = new XML(loader.data);
v_propiedades = new Array();
if (loader != null) {
for each(var nodo : XML in xmlExterno.elements()) {
v_propiedades[nodo.@nombre] = nodo.@valor;
trace("nombre: " + nodo.@nombre + ". valor: " + nodo.@valor);
trace("accedo a array " + nodo.@nombre + " su valor " + v_propiedades[nodo.@nombre]);
}
for (var s : String in v_propiedades) {
trace("propiedad " + s + " = " + v_propiedades[s]);
}
}else {
trace("loader is not a URLLoader!!!");
}
getPropiedad("nivelLog");
}
public static function getPropiedad(prop : String) : String {
// cuando llego a este método mi array de propiedades parece ser que está vacío
trace("Quieres el valor de la propiedad: " + prop);
trace("Este es su valor " + v_propiedades[prop]);
trace(" ");
trace("Recorro el array en getPropiedad()");
if (v_propiedades == null) {
trace("el array de propiedades es null");
}
for (var s : String in v_propiedades) {
trace("propiedad " + s + " = " + v_propiedades[s]);
}
trace("probando " + v_propiedades["nivelLog"]);
return v_propiedades[prop]
}
}
}
El problema es que en mi main, que es el siguiente
Código ActionScript :
package
{
import flash.display.MovieClip;
/**
* ...
* @author Lorena
*/
public class Main extends MovieClip {
private static var pro : Propiedades = Propiedades.getPropiedades();
public function Main() : void {
var nivelLog : String = Propiedades.getPropiedad("nivelLog");
trace("El valor tomado del fichero en nivelLog es: " + nivelLog);
}
}
}
Comienza a cargar el xml, pero se produce la llamada a la función getPropiedad antes de que el xml haya terminado de cargarse
Pongo a continuación la salida obtenida para que podais seguir por donde pasa:
Código :
[SWF] propiedades.swf - 3820 bytes tras la descompresión
Entro en getPropiedades()
Se inicializó una instancia de Propiedades
El array de propiedades es null
Quieres el valor de la propiedad: nivelLog
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at Propiedades$/getPropiedad()[C:\Users\Lore\Desktop\pruebas propiedades\Propiedades.as:72]
at Main()[C:\Users\Lore\Desktop\pruebas propiedades\Main.as:15]
at runtime::ContentPlayer/loadInitialContent()
at runtime::ContentPlayer/playRawContent()
at runtime::ContentPlayer/playContent()
at runtime::AppRunner/run()
at global/runtime::ADLEntry()
Estoy en cargarPropiedades
nombre: nivelLog. valor: DEBUG
accedo a array nivelLog su valor DEBUG
nombre: nombre. valor: fichero.log
accedo a array nombre su valor fichero.log
nombre: entorno. valor: local
accedo a array entorno su valor local
propiedad nivelLog = DEBUG
propiedad nombre = fichero.log
propiedad entorno = local
Quieres el valor de la propiedad: nivelLog
Este es su valor DEBUG
Recorro el array en getPropiedad()
propiedad nivelLog = DEBUG
propiedad nombre = fichero.log
propiedad entorno = local
probando DEBUG
¿De qué manera puedo solucionar este problema sin poner la función getPropiedad dentro del método cargarPropiedades?
Gracias, es que ando un poco pez con esto de la gestión de eventos
Un saludo
Lore