2009-08-20 5 views
0

J'ai créé une classe qui charge ses sous-classes en fonction d'un nom qui lui est passé. La fonction utilise getDefinitionByName, récupère le type de classe et l'instancie, et le renvoie si la classe est un sous-type de la classe qui possède cette méthode. Les sous-types sont tous des fichiers mxml qui étendent la classe de base, afin de simplifier l'instanciation des contrôles.Comportement étrange de getDefinitionByName

Cependant, dans le cas où je le passe un nom complet, il fonctionne dans mes tests unitaires mais échoue quand je l'exécute dans le contexte de mon application. Y a-t-il un getcha dans getDefinitionByName qui le fait se comporter différemment dans différents contextes d'exécution? Existe-t-il un moyen plus simple de charger des classes par leur nom qualifié?

static public function loadDisplay(className:String, extendedClassName:String = null):FeatureDisplay 
{ 
    try 
    { 
     trace("Loading", className); 
     var cls:Class = getDefinitionByName(className) as Class; 
     var display:FeatureDisplay = new cls() as FeatureDisplay; 
     if(display) 
     { 
      return display; 
     } 
     else 
     { 
      trace(className, "is not a subclass of FeatureDisplay"); 
      return null; 
     } 
    } 
    catch(error:Error) 
    { 
     trace("Error loading", className); 
     trace("Error:", error.message); 
    } 
    return null; 
} 

Répondre

2

Pour votre information, je l'ai vu la méthode suivante de garder les classes utilisées dans le code source de Flex:

// References.cs 

// notice the double reference: one to import, the other to reference 
import package.to.ClassA; ClassA; 
import package.to.ClassB; ClassB; 
import package.to.ClassC; ClassC; 

Bien sûr, vous devez toujours référencer la classe "References" quelque part.

3

Ma première question est vous explicitement utilisez l'une des classes partout? Si vous n'utilisez pas réellement une classe, même si elle est importée, ActionScript risque de ne pas conserver une copie de la définition de la classe dans le swf. Cela dit, il vaut mieux éviter getDefinitionByName, describeType, getQualifiedClassName ou getQualifiedSuperclassName si vous pouvez les éviter. Ils sont des porcs de la mémoire et il est généralement préférable de les éviter. (sauf si vous n'avez pas le contrôle sur les classes qui seront utilisées lors de l'exécution et ont à utiliser via getDefinitionByName).

Ma suggestion est que vous remplacez getQualifiedClassName par un swtich ... cas:

// Import the subclasses. 
import path.to.SpriteFeatureDisplay; 
import path.to.OtherFeatureDisplay; 

class FeatureDisplay extends Sprite{ 

    //Make one public static const per class. 
    public static const SPRITE_FEATURE_DISPLAY:String = "sprite_feature_display"; 
    public static const OTHER_FEATURE_DISPLAY:String = "other_feature_display"; 

    public static function loadDisplay( className:String, 
             extName:String = null):FeatureDisplay 
    { 
     trace("Loading", className); 

     // This will ensure that each of the classes is stored in the swf 
     // it will behave faster, and it is less prone to errors (note that 
     // try...catch is not needed). 
     swtich(className) 
     { 
      case SPRITE_FEATURE_DISPLAY: 
      return new SpriteFeatureDisplay(); 
      case OTHER_FEATURE_DISPLAY: 
      return new OtherFeatureDisplay(); 
      default: 
      trace("Requested class " + className + " could not be created..." + 
      "\nPlease make sure that it is a subclass of FeatureDisplay"); 
      return null; 
     } 
     return null; 
    } 
} 
+0

Il semble que vous l'ayez obtenu - les tests unitaires référencent explicitement le type pour s'assurer que le bon a été produit, et le code de l'application n'a pas fait. –